2017-07-10 16 views
1

私はそれがまだThread.sleep(2000)ですが致命的な例外:RxCachedThreadScheduler-1トリガーを破棄します。どうして?

disposable = Observable.create<String>({ 
    subscriber -> 
      try { 
       Thread.sleep(2000) 
       subscriber.onNext("Test") 
       subscriber.onComplete() 
      } catch (exception: Exception) { 
       subscriber.onError(exception) 
      } 
}).subscribeOn(Schedulers.io()) 
    .observeOn(AndroidSchedulers.mainThread()) 
    .subscribe({ result -> Log.d("Test", "Completed $result") }, 
      { error -> Log.e("Test", "Completed ${error.message}") }) 

が、私はdisposable?.dispose()コールを実行することを観察可能があり、次のRxJava 2のコードを(Kotlinで)、持っている、それは

FATAL EXCEPTION: RxCachedThreadScheduler-1 
Process: com.elyeproj.rxstate, PID: 10202 
java.lang.InterruptedException 
    at java.lang.Thread.sleep(Native Method) 
    at java.lang.Thread.sleep(Thread.java:371) 
    at java.lang.Thread.sleep(Thread.java:313) 
    at presenter.MainPresenter$loadData$1.subscribe(MainPresenter.kt:41) 
    at io.reactivex.internal.operators.observable.ObservableCreate.subscribeActual(ObservableCreate.java:40) 

私は期待してエラーになりますdisposeは、操作をサイレントモードでキャンセルするのに役立ちます。または、ほとんどの場合、サブスクライブのLog.eでエラーがキャッチされます。ただし、上記のエラーメッセージに従ってクラッシュするだけです。

なぜ例外がエスケープされたのですか? disposeは、クラッシュせずにすべての操作をサイレントモードでキャンセルするとは思いませんか?

答えて

2

要因の組み合わせがここにあります:使用するスレッドを処分もsubscribeOnを使用して、ストリームの

  1. dispose。これにはSchedulers.io()を使用するときはThread.interrupt()を呼び出します。これにより、例外が発生します。
  2. InterruptedExceptionは、Thread.sleepによって投げられたExceptionです。したがって、あなたのコードで捕捉され、他の例外と同様にonErrorに渡されます。
  3. の後にonErrorを呼び出すと、RxJava2のエラーが発生しないようにするため、エラーがグローバルエラーハンドラにリダイレクトされます。このチェックを回避するには、onErrorを呼び出す前に、またはRxJava 2.1.1の新しいsubscriber.tryOnErrorを使用してください。

    if (!subscriber.isDisposed()) { 
        subscriber.onError(exception) 
    } 
    
+0

おかげ@Kiskae。それは助ける! – Elye

関連する問題