我正在使用RxJava2处理使用Retrofit2下载的一些数据,将其保存到数据库中,并显示错误消息,并带有在失败时可以重试的选项。如果成功,则我需要发出另一个网络请求,处理该响应,如果该请求失败,则显示不同的错误消息。一切完成后,用户可以继续进入下一个屏幕。
我取得了一些成功,但似乎无法同时完成所有工作。我的某些任务被跳过,用户跳到链的末端,或者可观察对象没有按顺序运行。
这是我最近的尝试。
Disposable disposable = initializeMySdk()
.subscribeOn(Schedulers.computation())
.andThen(checkStatus())
.observeOn(AndroidSchedulers.mainThread())
.map(userStatus -> downloadAppData())
.flatMapCompletable((observable) ->
observable.flatMapCompletable((b) -> downloadUserData(getUserId())))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(() -> {
startNextActivity();
}, throwable -> Log.e(TAG, throwable.getMessage()));
initializeMySdk()
返回Completable。
checkStatus()
返回Single。
downloadAppData()
看起来像这样:
private Observable<Object> downloadAppData() {
return ApiUtils.downloadAppData()
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.doOnError(throwable -> {
mNoConnectionLayout.setVisibility(View.VISIBLE);
})
.retryWhen(throwableObservable -> RxView.clicks(mRetryBtn))
.flatMap(stringResponse -> handleNetworkResponse(stringResponse))
.observeOn(AndroidSchedulers.mainThread());
}
downloadUserData
与downloadAppData
类似,但是它没有一个带有“重试”按钮的对话框,它只是一个对话框,可以让您继续。这就是现在的工作方式,downloadUserData
没有被调用。我的flatMapCompletable
似乎有些有趣。
任何帮助将不胜感激!
更新
这是我现在的代码块:
Disposable disposable = initializeMySdk()
.subscribeOn(Schedulers.computation())
.andThen(checkStatus())
.flatMapCompletable(userStatus -> downloadAppData())
.andThen(downloadUserData(getUserId()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(() -> {
startNextActivity();
}, throwable -> Log.e(TAG, throwable.getMessage()));
现在问题似乎出在我的retryWhen
行中:
.retryWhen(throwableObservable -> RxView.clicks(mRetryBtn))
我收到此错误消息:
Expected to be called on the main thread but was RxComputationThreadPool-1
我尝试在整个代码中的多个位置添加.observeOn(AndroidSchedulers.mainThread())
,但没有任何运气。删除retryWhen
似乎可以解决我的问题,但是我需要能够重试。 ApiUtils.downloadAppData()
正在使用Retrofit2发出网络请求,因此无法在主线程上运行。
如果ApiUtils.downloadAppData()
抛出错误,则向用户显示一个错误屏幕,该屏幕有一个Retry
按钮,该按钮调用retryWhen
。为什么我无法在后台线程上运行ApiUtils.downloadAppData()
,显示错误屏幕并在主线程上观察retryWhen
,然后在后台线程上重试ApiUtils.downloadAppData()
,并能够尝试需要多少次?