添加RxJava2后,应用程序在SocketTimeout上崩溃

时间:2017-11-13 17:36:57

标签: android retrofit2 rx-java2

以前在我的应用中,我按顺序进行了两次API调用:isCategoryPromotedloadCategoryServices

我将RxJava2添加到项目中,以便请求可以并行完成。下面的代码总结了实现:

public class ServicesListViewModel{

    public final ObservableBoolean loading = new ObservableBoolean();
    public final ObservableField<String> loadServicesError = new ObservableField<>();

    public void start() {
        loading.set(true);

        final long categoryId = category.getCategoryId();

        final Disposable disposable = Flowable.combineLatest(
                categoriesRepository.isPromotedCategory(categoryId),
                categoriesRepository.loadServices(categoryId),
                (isPromoted, services) -> {

                    //..processing
                }
        ).doOnError(t -> {
            loading.set(false);
            loadServicesError.set(t.getMessage());
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe();
        compositeDisposable.add(disposable);
    }
}

public class ServicesListActivity extends BaseActivity{

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //inject viewmodel

        setupView();
        bindView();

        viewModel.start();
    }

    private void bindView() {
        loadingObserver = new Observable.OnPropertyChangedCallback() {
            @Override
            public void onPropertyChanged(Observable sender, int propertyId) {
                if (viewModel.loading.get()) {
                    showProgressDialog();
                } else {
                    hideProgressDialog();
                }
                binding.btnNext.setEnabled(!viewModel.loading.get());
            }
        };
        viewModel.loading.addOnPropertyChangedCallback(loadingObserver);

        loadServicesErrorObserver = new Observable.OnPropertyChangedCallback() {
            @Override
            public void onPropertyChanged(Observable sender, int propertyId) {
                showErrorDialog(viewModel.loadServicesError.get(), FINISH_ON_CLICK, false);
            }
        };
        viewModel.loadServicesError.addOnPropertyChangedCallback(loadServicesErrorObserver);

    }
}

当请求超时时,loadServicesError被设置,showErrorDialog中的代码成功执行。但是,在显示错误对话框之前,应用程序崩溃了。 LogCat中出现以下跟踪:

  

java.net.SocketTimeoutException:无法连接到my.api.com/   (端口443)在10000000ms之后从/192.168.0.10(端口49969):   isConnected失败:ETIMEDOUT(连接超时)       在libcore.io.IoBridge.isConnected(IoBridge.java:271)       在libcore.io.IoBridge.connectErrno(IoBridge.java:188)       在libcore.io.IoBridge.connect(IoBridge.java:130)       //..truncated ..       在com.myapp.networking.ApiFactory $ 2.intercept(ApiFactory.java:166)       //..truncated ..引起:android.system.ErrnoException:isConnected失败:ETIMEDOUT(连接超时)       在libcore.io.IoBridge.isConnected(IoBridge.java:262)... 37更多强制完成活动ServicesListActivity

stacktrace包含以下行:com.myapp.networking.ApiFactory$2.intercept(ApiFactory.java:166)

这是我拦截包含授权令牌的请求的地方:

builder.interceptors().add(new Interceptor() {
    @Override
    public Response intercept(Chain chain) throws IOException {
        final Request original = chain.request();

        Request.Builder newBuilder = original.newBuilder()
        newBuilder.addHeader("Authorization",apiDelegate.getAccessToken());

        return chain.proceed(request);//line in stack-tract
    }
});

我的问题是:如何处理此异常?

似乎系统决定需要完成Activity,因为请求超时。

在添加RxJava2之前,相同的代码工作正常,所以我很确定问题不在上面发布的代码之外。

我已经浏览了StackOverflow,似乎几乎所有的问题都表明只是增加了会话超时时间。我相信这是一个黑客攻击,应该有一个非常明智的方法来解决这个问题。

更新

CategoriesRepository.kt

override fun isPromotedCategory(categoryId: Long): Flowable<Boolean> = localSource.isPromotedCategory(categoryId)

override fun loadCategoryServices(categoryId: Long): Flowable<CategoryQuestions>
            = remoteSource.loadCategoryServices(categoryId)

CategoriesLocalDatsSource.kt

override fun isPromotedCategory(categoryId: Long): Flowable<Boolean> {
    return Flowable.create<Boolean>({ subscriber ->
        val isPromotedCategory = dbHelper.promotedCategoryDao.idExists(categoryId)

        subscriber.onNext(isPromotedCategory)
        subscriber.onComplete()
    }, BackpressureStrategy.BUFFER)
}

CategoriesRemoteDataSource.kt

override fun loadCategoryServices(categoryId: Long): Flowable<CategoryServices> {
    return Flowable.create<CategoryServices>({
        service().loadCategoryServices(categoryId)
                .enqueue(object : ApiCallback<CategoryServices>() {
                    override fun success(services: CategoryServices?, response: Response<*>?) {
                        it.onNext(services)
                        it.onComplete()
                    }

                    override fun failure(throwable: Throwable?) {
                        it.onError(throwable)
                    }
                })
    }, BackpressureStrategy.BUFFER)
}

1 个答案:

答案 0 :(得分:1)

正如@Bob Dalgleish所说onError并没有按照你的预期做到。 subscribe()有多个参数可用于反映结果,第二个参数是您认为的“onError”。请记住,异常是流终端事件,这意味着流在异常后变得不可用,除非您添加错误处理运算符,例如onErrorReturn()