RxJava未调用onSuccess或onError,应用程序冻结。

3
当我关闭互联网并在第一次下拉刷新时,一切正常(禁用刷新,并显示“NetworkErrorView”),但是当我在第二次下拉刷新时,刷新状态会冻结。我理解在SingleObserver中既不调用onSuccess(因为没有网络,没问题),也不调用onError,因为互联网关闭,结果doAfterTerminate也不被调用。
顺便说一下,dataManager.getCitiesFromDb()返回Observable(City),而dataManager.getCityConditionsResponse()返回Single(List(City))。
MainActivity(onCreate)
presenter.setRefreshObservable(RxSwipeRefreshLayout.refreshes(swipeRefreshLayout));

演示者

@Override
public void setRefreshObservable(Observable<Object> observable) {
    observable
            .flatMapSingle(l -> getCitiesListObservable()
                    .flatMap(list -> Single.fromObservable(Observable.fromIterable(list)))
                    .map(city -> city))
            .toList()
            .subscribe(new SingleObserver<List<City>>() {
                @Override
                public void onSubscribe(Disposable d) {
                    disposables.add(d);
                }

                @Override
                public void onSuccess(List<City> list) {
                    view.showCitiesList(list);
                }

                @Override
                public void onError(Throwable e) {
                    view.showNetworkErrorView();
                }
            });
}

private Single<List<City>> getCitiesListObservable() {
    return dataManager.getCitiesFromDb()
            .flatMapSingle(city ->
                    dataManager.getCityConditionsResponse(city.getQuery())
                            .map(response -> {
                                city.setTemp(response.getTemp());
                                city.setIcon(response.getIcon());
                                return city;
                            })
            )
            .toList()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .doAfterTerminate(() -> view.hideRefreshingStatus());
}

你能展示一下日志吗? - Tam Pham
问题已经在第一个答案中解决了,问题是由于连接错误导致的。 - Mike
1个回答

3
如果在RxJava中,一个observable发出了错误,那么它将被终止,因此您无法再次使用该流。
在您的情况下,当您的网络请求(可能是dataManager.getCityConditionsResponse方法)由于互联网问题而导致错误时,您的流就会中断。
为了处理这个问题,您需要在网络请求中添加RxJava的onErrorReturn,以便不发出错误。由于它不会向下游发出错误,因此您的流不会中断。最终,它可以继续发出更多的项目。

所以使用这种方法,我可以创建一个带有布尔变量的StateUtils类。在onErrorReturn中,我将使用该变量进行初始化,并且不返回列表而是返回null。然后所有的错误处理都将只在onSuccess中进行,因为由于onErrorReturn方法,不会调用onError。例如,如果布尔值为true,则显示网络错误,如果为false,则显示服务器错误。 - Mike
我理解你的意思,但请回答最后一个问题:在网络调用中更好的是在onErrorReturn之前调用,还是在toList()之后(网络调用后)调用,或者这并不重要。 - Mike
等一下,我刚才删除了我的上一个评论,因为我误解了它。 你必须把它放在网络调用之后,那是导致错误的地方。 - bkrcinar
那么,在我的代码中,是在map之后(因为从数据库中获取的城市是可迭代的observable),还是在toList()之后?我认为在toList()之后,这可以防止在StateModel类中多次初始化值,如果出现错误。 - Mike
你说得对,我的代码中有网络调用循环。如果出现错误,我想要停止循环(获取城市条件),并初始化 StateModel 类的变量,以便进一步处理错误(显示网络或服务器错误视图)。 - Mike
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接