RxAndroid可观察循环

时间:2017-08-21 09:13:57

标签: android retrofit rx-java rx-android

所以我正在开发一个由其他人开发的旧项目,并且在项目中使用了RxAndroid。 我不得不在一些应用程序的请求中添加缓存处理,并且OkHttp缓存在我需要的时候没有做好。所以我提出了实现我自己的服务的解决方案,它检查互联网连接,然后发出请求,或根据连接从缓存中读取它。我没有RxAndroid的经验,但我读了一下,我想出了这个:

@Override
public Observable<List<SocialNews>> getStream(@Path("stream") String stream, @Query("networks") String networks, @Query("page") Integer page, @Query("limit") Integer limit) {
    return Observable.create(new AsyncOnSubscribe<Object, List<SocialNews>>() {
        @Override
        protected Object generateState() {
            return null;
        }

        @Override
        protected Object next(Object state, long requested, Observer<Observable<? extends List<SocialNews>>> observer) {
            if (NetworkUtils.hasActiveInternetConnection(context)) {
                observer.onNext(APIClient.getService(context).getStream(stream, networks, page, limit));
            } else {
                observer.onNext(Observable.just(NetworkUtils.getCachedStream()));
            }
            return state;
        }
    });
}

我订阅它是这样的:

 final Observable<List<SocialNews>> observable = APIClient.getCacheService(getActivity()).getStream(stream, networks, page, SportFiveAPI.DEFAULT_ITEM_LIMIT);
    LifecycleObservable.bindFragmentLifecycle(lifecycle(),
            AppObservable.bindFragment(this, observable)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread()))
            .subscribeOn(Schedulers.io())
            .subscribe(
                    socialNews -> {
                        // do stuff
                    },
                    error -> {
                        // do stuff
                    }
            );

但不知怎的,它陷入循环并继续调用我的AsyncOnSubscribe中的下一个方法。谁知道我在这里做错了什么?

2 个答案:

答案 0 :(得分:2)

您没有在观察者身上致电onCompleted

答案 1 :(得分:2)

最好使用Observable.fromCallable Observable.create,以避免违反代码中的Observable合同 - 即不调用onCompleted }。我推荐这样的东西:

@Override
public Observable<List<SocialNews>> getStream(@Path("stream") String stream, @Query("networks") String networks, @Query("page") Integer page, @Query("limit") Integer limit) {
Observable.fromCallable(() -> NetworkUtils.hasActiveInternetConnection(context))
          .flatMap(hasConnection -> {
            if (hasConnection) {
                return APIClient.getService(context).getStream(stream, networks, page, limit);
            } else {
                return Observable.just(NetworkUtils.getCachedStream())
            }
          })
}

此外,使用concatfirst进行此类回退类型数据检索有一个非常好的模式。有关详细信息,请参阅Dan Lew的this