RxJava-订阅未捕获导致崩溃的异常

时间:2018-09-23 13:27:19

标签: kotlin rx-java2

我正在尝试订阅SingleSource,我已经实现了onSuccess方法的onErrorsubscribe,这是我的代码:

disposable.add(repository
                .getUser1()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({
                    toast(it)
                }, {
                    toast(it.message ?: "Error")
                }))

问题是,当存储库中发生异常时,不会在onError中捕获该异常

这是我的存储库实现:

class Repository(private val sp: SharedPreferences) {

    // It crashes
    fun getUser1(): Single<String> = generateUser(name, "Hello")

    // it doesn't crash
    fun getUser2(): Single<String> = Single.fromCallable { name }.flatMap { generateUser(it, "Hello") }

    private var name: String
        get() = sp.getString("user", null) ?: throw NoNameException()
        set(value) = sp.edit().putString("user", value).apply()

    private fun generateUser(name: String, message: String): Single<String> = Single.just("$message $name")

}

这是崩溃日志:

  

09-24 10:13:40.930 6934-6934 / com.mosius.samplerxtest E / AndroidRuntime:   致命异常:主要       流程:com.mosius.samplerxtest,PID:6934       java.lang.RuntimeException:java.lang.reflect.InvocationTargetException           在com.android.internal.os.RuntimeInit $ MethodAndArgsCaller.run(RuntimeInit.java:503)           在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:826)        造成原因:java.lang.reflect.InvocationTargetException           在java.lang.reflect.Method.invoke(本机方法)           在com.android.internal.os.RuntimeInit $ MethodAndArgsCaller.run(RuntimeInit.java:493)           在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:826)        引起原因:com.mosius.samplerxtest.NoNameException:没有提供名称           在com.mosius.samplerxtest.Repository.getName(Repository.kt:17)           在com.mosius.samplerxtest.Repository.getUser1(Repository.kt:10)           在com.mosius.samplerxtest.MainActivity $ onCreate $ 1.onClick(MainActivity.kt:24)           在android.view.View.performClick(View.java:6597)           在android.view.View.performClickInternal(View.java:6574)           在android.view.View.access $ 3100(View.java:778)           在android.view.View $ PerformClick.run(View.java:25881)           在android.os.Handler.handleCallback(Handler.java:873)           在android.os.Handler.dispatchMessage(Handler.java:99)           在android.os.Looper.loop(Looper.java:164)           在android.app.ActivityThread.main(ActivityThread.java:6649)           在java.lang.reflect.Method.invoke(本机方法)           在com.android.internal.os.RuntimeInit $ MethodAndArgsCaller.run(RuntimeInit.java:493)           在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:826)

这两种实现之间有什么区别?

1 个答案:

答案 0 :(得分:0)

getUser1()方法中,尚未创建SingleSource,因此Rx无法控制该异常。

在第二个中,名称是在Rx范围中获取的,因此它可以处理异常