RxJava Android - 在适当的线程上加载缓存显示数据

时间:2014-06-26 10:25:23

标签: android multithreading caching rx-java

我正在探索RxJava及其对Android的适用性,并且我尝试实现一个简单的加载缓存显示用例,如下面的ASCII图所示:

                    ---------------
      --- failure --|  Load data  |-- success ---
      |             ---------------             |
      V                                         V
-------------------                       -------------
|  Get from cache |                       |   Filter  |
-------------------                       -------------
      |                                         |
      |                                         V
      |            ----------------       -------------
      ------------>|    Display   |<------|    Cache  |
                   ----------------       -------------

这是我最初提出的代码:

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);
                    }
                });

正如所料,网络和缓存是在后台线程上执行的,并且显示数据发生在UI线程上。问题是onErrorReturn()返回的数据经历了相同的过滤和缓存周期,这是多余的。但是,如果我将代码更改为:

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()。构建这些可观察对象以实现我的方案的正确方法是什么?

1 个答案:

答案 0 :(得分:5)

使用onErrorReturn()

替换onErrorResumeNext(Observable.just(itemsDao.getCachedItems()))来电解决