Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxJava instead of AsyncTask?

I came across several instances when people were trying to persuade me into using RxJava instead of Android's standard AsyncTask construct.

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?

like image 687
qantik Avatar asked Aug 29 '16 19:08

qantik


1 Answers

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.

like image 179
Tassos Bassoukos Avatar answered Oct 05 '22 00:10

Tassos Bassoukos