qantik qantik - 3 months ago 9
Android Question

RxJava instead of AsyncTask; Pros and Cons

lately I came across several instances when people were trying to persuade me into using RxJava instead of Android's standard AsyncTask construct, especially since I've made extensive use of AsyncTask in an ongoing project.

In my opinion RxJava offers a lot more features but loses in simplicity against AsyncTask.

Are there any use cases that suit one approach better than the other or even more general can RxJava even be considered superior?

Thanks in advance.

Answer

The full power of RxJava is visible when you use it on Java 8, preferably with a library like Retrofit. It allows you to trivially chain operations together, with full control of error handling. For example, consider the following code given id: an int that specifies the order and apiClient: a Retrofit client for the order management microservice:

apiClient
.getOrder(id)
.subscribeOn(Schedulers.io())
.flatMapIterable(Order::getLineItems)
.flatMap(lineItem ->
    apiClient.getProduct(lineItem.getProductId())
             .subscribeOn(Schedulers.io())
             .map(product -> product.getCurrentPrice() * lineItem.getCount()),
    5)
.reduce((a,b)->a+b)
.retryWhen((e, count) -> count<2 && (e instanceof RetrofitError))
.onErrorReturn(e -> -1)
.subscribe(System.out::println);

This will asynchronously calculate the total price of an order, with the following properties:

  • at most 5 requests against the API in flight at any one time (and you can tweak the IO scheduler to have a hard cap for all requests, not just for a single observable chain)
  • up to 2 retries in case of network errors
  • -1 in case of failure (an antipattern TBH, but that's an other discussion)

Also, IMO the .subscribeOn(Schedulers.io()) after each network call should be implicit - you can do that by modifying how you create the Retrofit client. Not bad for 11+2 lines of code, even if it's more backend-ish than Android-ish.

Comments