Rx异常处理失败

时间:2018-12-05 09:19:22

标签: android kotlin retrofit2 rx-java2

我正在使用经过改进的RxJava进行API调用,

通过使用诸如 flatMap map 之类的RxJava方法,我正在进行API调用,并在后台线程中在会议室数据库中执行数据库操作。

我的实现是完美的,并且在没有错误的情况下也可以正常工作,但是在执行数据库操作时遇到错误或任何异常的情况下,应用程序会由于跟随Rx错误而崩溃。

E/AndroidRuntime: FATAL EXCEPTION: RxCachedThreadScheduler-1

The exception was not handled due to missing onError handler in the subscribe() method call.

我已经使用RxJava执行以下操作:

mDataManager.login(params)
                .flatMap { loginResponse: LoginResponse ->

                    // here making another API call based on previos API result
                    return@flatMap mDatamanager....
                }
                .flatMap { object: SomeDataModel ->

                    // here inserting data to DB
                    mDataManager.insertDataToDB(object).subscribe()

                    // here making another API call based on previos API 
                    return@flatMap mDataManager...
                }.map {

                    // here inserting data to DB
                    mDataManager.insertDataToDB(object).subscribe()

                    return@map true
                }
                .observeOn(mSchedulerProvider.ui())
                .subscribeOn(mSchedulerProvider.io())
                .subscribe({ result ->
                    // updating view
                }, { throwable ->
                    throwable.printStackTrace()
                })

将数据插入数据库时​​出现异常

异常java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase:

但是错误没有得到处理,应用程序崩溃了。

该错误表明missing onError handler in the subscribe() method,但是在我的代码中,我已经覆盖了throwable以处理异常/错误。

任何人都可以找到我所缺少的或我在代码中犯的错误。


更新

找到了解决方案,错误就在这里:

mDataManager.insertDataToDB(object).subscribe()

在上述声明中,我正在订阅但未处理该错误,并且由于该错误未由rxJava处理,结果导致应用程序崩溃。

最终代码如下:

mDataManager.login(params)
            .flatMap { loginResponse: LoginResponse ->

                // here making another API call based on previos API result
                return@flatMap mDatamanager....
            }
            .flatMap { object: SomeDataModel ->

                // avoid this inner subscribe
                // mDataManager.insertDataToDB(object).subscribe()

                return@flatMap mDataManager.insertDataToDB(object)
            }
            .flatMap {
                // here making another API call based on previos API result
                return@flatMap mDatamanager....
            }
            .flatMap {

                // avoid this inner subscribe
                //mDataManager.insertDataToDB(object).subscribe()

                return@flatMap mDataManager.insertDataToDB(object)
            }
            .observeOn(mSchedulerProvider.ui())
            .subscribeOn(mSchedulerProvider.io())
            .subscribe({ result ->
                // updating view
            }, { throwable ->
                throwable.printStackTrace()
            })

以上代码运行正常!

1 个答案:

答案 0 :(得分:1)

原因是您在这里订阅

.map {
    // here inserting data to DB
    mDataManager.insertDataToDB(object).subscribe()
    return@map true
}

并且此订阅未处理错误情况。

我觉得调用内部流的subscribe()不是一个好习惯。在您的方案中,流程是在两者之间中断的。

对我来说,最好的方法是使用map而不是使用map并在此处调用subscribe(),

flatMap{
    object -> mDataManager.insertDataToDB(object)
}

这样,如果有任何错误,它将被捕获到最后一个外部的subscription()中。

希望这个答案有帮助。