I'm exploring the RxJava and its applicability to Android, and I'm trying to implement a simple load-cache-display use case, as depicted on the following ASCII graph:
---------------
--- failure --| Load data |-- success ---
| --------------- |
V V
------------------- -------------
| Get from cache | | Filter |
------------------- -------------
| |
| V
| ---------------- -------------
------------>| Display |<------| Cache |
---------------- -------------
Here's the code that I initially came up with:
subscription = AndroidObservable.bindFragment(this, restClient.getItems())
.onErrorReturn(new Func1<Throwable, List<Item>>() {
@Override public List<Item> call(Throwable throwable) {
return itemsDao.getCachedItems();
}
})
.flatMap(new Func1<ItemContainer, Observable<Item>>() {
@Override public Observable<Item> call(ItemContainer itemContainer) {
return Observable.from(itemContainer.getItems());
}
})
.filter(new Func1<Item, Boolean>() {
@Override public Boolean call(Item item) {
return item.getName().startsWith("B");
}
})
.toList()
.map(new Func1<List<Item>, List<Item>>() {
@Override public List<Item> call(List<Item> items) {
itemsDao.cacheItems(items);
return items;
}
})
.subscribeOn(Schedulers.from(AsyncTask.THREAD_POOL_EXECUTOR))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<List<Item>>() {
@Override public void call(List<Item> items) {
displayData(items);
}
});
As expected, networking and caching are performed on a background thread, and displaying the data happens on UI thread. The problem is that data returned by onErrorReturn()
goes through the same filtering and caching cycle, which is redundant. However, if I change the code to this:
subscription = AndroidObservable.bindFragment(this, restClient.getItems())
.flatMap(new Func1<ItemContainer, Observable<Item>>() {
@Override public Observable<Item> call(ItemContainer itemContainer) {
return Observable.from(itemContainer.getItems());
}
})
.filter(new Func1<Item, Boolean>() {
@Override public Boolean call(Item item) {
return item.getName().startsWith("B");
}
})
.toList()
.map(new Func1<List<Item>, List<Item>>() {
@Override public List<Item> call(List<Item> items) {
itemsDao.cacheItems(items);
return items;
}
})
.onErrorReturn(new Func1<Throwable, List<Item>>() {
@Override public List<Item> call(Throwable throwable) {
return itemsDao.getCachedItems();
}
})
.subscribeOn(Schedulers.from(AsyncTask.THREAD_POOL_EXECUTOR))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<List<Item>>() {
@Override public void call(List<Item> items) {
displayData(items);
}
});
displayData()
is never called. What would be the right way to compose these observables to implement the scheme that I have?
RxJava has made life easy for all the Android developers using it. In this blog, we are going to discuss RxJava for Android specifically. What is RxJava? What is RxAndroid? What is RxJava? RxJava is a JVM library for doing asynchronous and executing event-based programs by using observable sequences.
Understanding Caching in Android. When the user launches the program for the first time, there will be no data in memory and no data in the disc cache. As a result, the application will need to make a network call to retrieve the data. It will retrieve data from the network, store it to disc, retain it in-memory cache, and then return the data.
RxAndroid introduced the Main Thread required for Android. To work with the multithreading in Android, we will need the Looper and Handler for Main Thread execution. RxAndroid provides AndroidSchedulers.mainThread () which returns a scheduler and that helps in performing the task on the main UI thread that is mainly used in the Android project.
RxAndroid provides AndroidSchedulers.mainThread () which returns a scheduler and that helps in performing the task on the main UI thread that is mainly used in the Android project. So, here AndroidSchedulers.mainThread () is used to provide us access to the main thread of the application to perform actions like updating the UI.
Solved by replacing onErrorReturn()
call with onErrorResumeNext(Observable.just(itemsDao.getCachedItems()))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With