首页 > 解决方案 > 如何在有限的时间内添加 retryWhen()(例如仅重试 3 次)获取 IOException

问题描述

我正在使用 3 个 Web API 调用从服务器获取响应,但如果出现 IOException,我必须使用 retryWhen() 重试这些调用 3 次。
我怎样才能做到这一点?

我尝试添加以下代码,但没有得到预期的输出

retryWhen(new Function<io.reactivex.Observable<Throwable>, ObservableSource<?>>() {
                    int retryCount = 0;

                    @Override
                    public ObservableSource<?> apply(io.reactivex.Observable<Throwable> errors) throws Exception {

                        return errors.flatMap(new Function<Throwable, ObservableSource<?>>() {
                            @Override
                            public ObservableSource<?> apply(Throwable throwable) throws Exception {
                                retryCount++;
                                if (retryCount < 4) {
                                    Log.e(TAG, " Exception retrying = "+retryCount );
                                    return io.reactivex.Observable.just("");
                                }
                                return io.reactivex.Observable.error(throwable);
                            }
                        });
                    }
                })

public void onClickLogin(View view) {

             io.reactivex.Observable
             .zip(getLogin(Constants.EMAILID, Constants.PASSWORD),
             getUserInfo(Constants.EMAILID, Constants.PASSWORD),
            getProductDetails(Constants.EMAILID, Constants.PASSWORD).subscribeOn(Schedulers.io()),
                                .observeOn(AndroidSchedulers.mainThread())
                        new Function3<List<LoginModule>,
                                List<UserInfoModule>, ProductModule, AllZipData>() {
                            @Override
                            public AllZipData apply(List<LoginModule> loginModuleList, List<UserInfoModule> useerInfoModules, ProductModule productModule) throws Exception {

                                AllZipData allZipData = new AllZipData();
                                allZipData.setLoginModuleList(loginModuleList);
                                allZipData.setUserInfoModuleList(UserInfoModule);
                                allZipData.setProductModule(productModule);

                                return allZipData;
                            }
                        }).subscribe(new Observer<AllZipData>() {
            @Override
            public void onSubscribe(Disposable d) {
                compositeDisposable.add(d);
            }

            @Override
            public void onNext(AllZipData allZipData) {


                MyDatabase MyDatabase = MyDatabase.getInstance(context);

                for (int i = 0; i < allZipData.getUserInfoModuleList().size(); i++) {

                    UserInfoTable userInfoTable = new UserInfoTable();
                    userInfoTable.setValue1(allZipData.getUserInfoModuleList().get(i).getValue1());
                    userDatabase.userDao().insertUserInfo(userInfoTable);
                }

            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "onError: all zip data " + e.toString());
            }

            @Override
            public void onComplete() {
                Log.e(TAG, "onComplete: all data zipped");
            }
        });
}

标签: androidretrofit2rx-android

解决方案


有一个重试版本,它调用一个谓词来确定是否应该订阅流 - 如果你应该重试。谓词接收 2 个参数 -number of attemptsthrowable. 这似乎是你想要的。我会尝试:

observableThatMightError
   .retry((count, throwable) -> throwable instanceof IOExceptio && count <= 3)

如果 throwable 是 anIOException并且您还没有重试至少 3 次,这将重试。


推荐阅读