我有两个API调用 1.)配置文件获取 2.)Feeds Fetch
我需要加载缓存(如果存在),否则去网络。
如果存在缓存,则在后台调用网络时加载它
使用CONCAT操作
例如。 concat(feedlocal, feednetwork)
并且一旦收到网络呼叫,就使用DiffUtils(android)
更新循环视图同样:concat(profilelocal, profilenetwork)
问题:
我正在使用zip(c1,c2)(道歉,如果使用了错误的东西) 但问题是网络响应从未通过zip操作响应。
我需要首先显示缓存,并在收到网络呼叫时更新ui并使其并行(Feed + Profile)
修改
private Observable<List<FeedProfileResponse>> getProfileObservable(){
//local
Observable<List<FeedProfileResponse>> local = Observable.fromCallable(() ->
dataManager.getCacheValueOf(DB_FEED_PROFILE_LIST) != null ?
new Gson().fromJson(dataManager.getCacheValueOf(DB_FEED_PROFILE_LIST)
, new TypeToken<List<FeedProfileResponse>>() {
}.getType()) :
Collections.<FeedProfileResponse>emptyList())
.subscribeOn(schedulerProvider.computation())
.observeOn(AndroidSchedulers.mainThread())
.doOnError(Throwable::printStackTrace)
.onErrorResumeNext(Observable.empty());
//network
Observable<List<FeedProfileResponse>> network = apiHelper.fetchFeedProfile(dataManager.getCurrentUserId().intValue()
, mProfileCurrentPage)
.map(responses -> {
//Cache Updates
Observable.create(subscriber -> {
updateCacheDao(dataManager.getCacheObj(DB_FEED_PROFILE_LIST),
new Gson().toJson(responses), DB_FEED_PROFILE_LIST,
NetworkUtils.getCurrentTimeStamp());
subscriber.onComplete();
})
.subscribeOn(schedulerProvider.computation())
.subscribe();
return responses;
})
.subscribeOn(schedulerProvider.io())
.doOnError(Throwable::printStackTrace)
.onErrorResumeNext(Observable.empty());
CacheData cacheObj = dataManager.getCacheObj(DB_FEED_PROFILE_LIST);
return cacheObj != null ? !NetworkUtils.hasTimestampExpired(cacheObj.getUpdatedAt())
&& cacheObj.getUpdatedAt() > dataManager.getAppTimestamp() ?
local.observeOn(AndroidSchedulers.mainThread()) :
Observable.concat(local, network).observeOn(AndroidSchedulers.mainThread()) : network.observeOn(AndroidSchedulers.mainThread());
}
private Observable<List<FeedReviewResponse>> getReviewObservable() {
//local
Observable<List<FeedReviewResponse>> local = Observable.fromCallable(() ->
dataManager.getCacheValueOf(DB_FEED_REVIEW_LIST) != null ?
new Gson().fromJson(dataManager.getCacheValueOf(DB_FEED_REVIEW_LIST)
, new TypeToken<List<FeedReviewResponse>>() {
}.getType()) :
Collections.<FeedReviewResponse>emptyList())
.subscribeOn(schedulerProvider.computation())
.observeOn(AndroidSchedulers.mainThread())
.doOnError(Throwable::printStackTrace)
.onErrorResumeNext(Observable.empty());
//network
Observable<List<FeedReviewResponse>> network = apiHelper.fetchFeedReviews(dataManager.getCurrentUserId().intValue(),
AppConstants.FeedReviewConstants.KEY_API_PARAM_1, AppConstants.FeedReviewConstants.KEY_API_PARAM_2,
mCurrentPage)
.map(responses -> {
isFeedReviewLastPage = !(responses.size() == AppConstants.FeedReviewConstants.PAGE_SIZE);
//Cache Updates
Observable.create(subscriber -> {
updateCacheDao(dataManager.getCacheObj(DB_FEED_REVIEW_LIST),
new Gson().toJson(responses), DB_FEED_REVIEW_LIST,
NetworkUtils.getCurrentTimeStamp());
subscriber.onComplete();
})
.subscribeOn(schedulerProvider.computation())
.subscribe();
return responses;
})
.subscribeOn(schedulerProvider.io())
.doOnError(Throwable::printStackTrace)
.onErrorResumeNext(Observable.empty());
CacheData cacheObj = dataManager.getCacheObj(DB_FEED_REVIEW_LIST);
return cacheObj != null ? !NetworkUtils.hasTimestampExpired(cacheObj.getUpdatedAt())
&& cacheObj.getUpdatedAt() > dataManager.getAppTimestamp() ?
local.observeOn(AndroidSchedulers.mainThread()) :
Observable.concat(local, network).observeOn(AndroidSchedulers.mainThread()) : network.observeOn(AndroidSchedulers.mainThread());
}
private void zipProfileAndReview(Observable<List<FeedReviewResponse>> reviewObservable,
Observable<List<FeedProfileResponse>> profileObservable){
compositeDisposable.add(Observable.zip(reviewObservable, profileObservable,
ProfileAndReview::new)
.doOnNext(profileAndReview -> {
getMvpView().setRefreshing(false);
})
.subscribeOn(schedulerProvider.computation())
.observeOn(AndroidSchedulers.mainThread())
.onErrorResumeNext(Observable.empty())
.subscribeOn(schedulerProvider.io())
.subscribe(profileAndReview -> {
getMvpView().setFeedReviewListData(profileAndReview.getFeedReviewResponses());
getMvpView().setFeedProfileListData(profileAndReview.getFeedProfileResponses());
isFeedReviewLastPage = !(profileAndReview.getFeedReviewResponses().size() == AppConstants.FeedReviewConstants.PAGE_SIZE);
isFeedProfileLastPage = !(profileAndReview.getFeedProfileResponses().size() == AppConstants.FeedProfileConstants.PAGE_SIZE);
}, Throwable::printStackTrace));
}
答案 0 :(得分:0)
getProfileObservable()
和getReviewObservable()
涉及两个用于返回语句的三元运算符,它复杂且根本不可读。您确定Observable.concat(local, network)
是您在测试期间调用的那个吗?
还有一些评论:
您应该在zip()
中使用combineLatest
代替zipProfileAndReview
。为了使所有值都由zip()
处理,您应该为每个源提供完全相同的值。如果获得高速缓存无效或网络调用失败,则仅使用另一个源的第一个值。这甚至可能是您问题的根源。
您最好使用doOnNext()
代替//Cache Updates
部分的地图,因为您没有转换(映射)该值,只是做副作用。
您不需要精确调度所有方式。只需在.subscribeOn(schedulerProvider.io()).observeOn(AndroidSchedulers.mainThread())
中写一次zipProfileAndReview()
。