Rxjava2- Android(Concat + Zip)可能吗?

时间:2018-03-14 08:46:36

标签: android android-recyclerview rx-java rx-java2 rx-android

我有两个API调用 1.)配置文件获取 2.)Feeds Fetch

我需要加载缓存(如果存在),否则去网络。

如果存在缓存,则在后台调用网络时加载它

使用CONCAT操作 例如。 concat(feedlocal, feednetwork)

并且一旦收到网络呼叫,就使用DiffUtils(android)

更新循环视图

同样:concat(profilelocal, profilenetwork)

问题:

我正在使用zip(c1,c2)(道歉,如果使用了错误的东西) 但问题是网络响应从未通过zip操作响应。

https://dl2.pushbulletusercontent.com/giQolwcSSPZrBxwiUQoFbsQ7FMxBRr8w/4vgkDWPUoU5Pb8sQsLa0bbAURs7gKi0ncyIoluD7bqU2EeOk-FJnJudUvKjB5hwNY0bm7Yt_kl9wgZ5aC4a567PCxpUhnoNxUJWEcO6i0VY89QQDsTU3uZ

我需要首先显示缓存,并在收到网络呼叫时更新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));
}

1 个答案:

答案 0 :(得分:0)

getProfileObservable()getReviewObservable()涉及两个用于返回语句的三元运算符,它复杂且根本不可读。您确定Observable.concat(local, network)是您在测试期间调用的那个吗?

还有一些评论:

  • 您应该在zip()中使用combineLatest代替zipProfileAndReview。为了使所有值都由zip()处理,您应该为每个源提供完全相同的值。如果获得高速缓存无效或网络调用失败,则仅使用另一个源的第一个值。这甚至可能是您问题的根源。

  • 您最好使用doOnNext()代替//Cache Updates部分的地图,因为您没有转换(映射)该值,只是做副作用。

  • 您不需要精确调度所有方式。只需在.subscribeOn(schedulerProvider.io()).observeOn(AndroidSchedulers.mainThread())中写一次zipProfileAndReview()