RxJava Android在网络之前返回缓存

时间:2017-03-27 16:17:33

标签: android caching rx-java

我正在尝试快速返回一个缓存observable,然后在完成后更新UI的网络请求。

使用Rx startWith,如果手机处于信号状态,则工作正常,但是如果我将手机置于飞行模式,那么改装网络调用就会很快失败onError,从startWith返回的缓存值永远不会被返回,因为onError终止了observable立即。我还需要知道observable是否抛出onError以显示给用户。我的缓存几乎是即时的,所以我宁愿在尝试任何网络调用之前返回缓存。有办法整齐地做到这一点吗?还是更好的方法呢?

public Observable<String> getMyString(String key){
        WebRequestDbEntity myCachedString = mCache.getWebRequest(key);
        String cachedString = myCachedString.getValue();

        return retrofitWebDataStore().getMyString(key)
                .startWith(Observable.just(cachedString))
                .map(networkString -> {
                    mCache.saveRequest(key, networkString);
                    return networkString;
                });
    }

在表示层中:

        getMyString(key)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(this::onSuccess, this::onError);

2 个答案:

答案 0 :(得分:1)

观察observable时...使用observeOn(AndroidSchedulers.mainThread,true)。真实的是延迟错误。这允许缓存observable在网络observable抛出错误之前返回。

getMyString(key)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread(), true)
                    .subscribe(this::onSuccess, this::onError);

答案 1 :(得分:0)

你可能需要考虑使用concat(),将缓存作为第一个Observable,这样你就可以确保在启动网络Observable之前返回缓存结果(如果有的话)。像这样的东西:

Observable<String> cacheObservable = Observable.fromCallable(() -> {
    WebRequestDbEntity myCachedString = mCache.getWebRequest(key);
    return myCachedString.getValue();
});
Observable<String> serverObservable =
        retrofitWebDataStore().getMyString(key)
                .doOnNext(networkString -> mCache.saveRequest(key, networkString));

return Observable.concat(cacheObservable, serverObservable);

这样,你确保返回第一个缓存对象(你的示例中没有处理任何缓存情况,但是它可以通过检查没有缓存结果和过滤来轻松解决,因此缓存Observable要么返回结果,要么只是完全没有任何东西),你将首先在表示逻辑中处理它。之后,网络请求将启动,如果你得到结果,你将把它保存到doOnNext()的缓存中(在你的例子中你也用缓存的结果做了,不确定这是不是你想要的),而且只有错误可能是由网络请求引起的,但不会使缓存不返回值,因为它在缓存提取后发生。