2017-10-04 101 views
1

我試圖通過創建一個單一的實例DisposableSingleObserver/DisposableObserver並通過它通過subscribeWith()方法在像下面的流上重複使用觀察者的單一和Observable流:使用配置的觀察者不重新訂閱源

public class SomeClass { 
    private DisposableSingleObserver<Object> observer; 

    public SomeClass() { 
     observer = new DisposableSingleObserver<Object>() { 
      @Override 
      public void onSuccess(Object object) { 
       ... 
      } 

      @Override 
      public void onError(Throwable throwable) { 
       ... 
      } 
     }; 
    } 

    public void doSomeStuff() { 
     singleStream.subscribeOn(...) 
      .observeOn(...) 
      .subscribeWith(observer); 
    } 
} 

上面的代碼導致ProtocolViolationException當我試圖與單個觀察者實例多次使用消息訂閱:

io.reactivex.exceptions.ProtocolViolationException:不允許訂閱瓦特ith(n)com.package.name.SomeClass $ 1多次。請創建一個新的com.package.name.SomeClass $ 1實例,然後將其訂閱到目標源。

所以我修改了代碼有點像下面:

public class SomeClass { 
    ... 

    public void doSomeStuff() { 
     if (observer != null) { 
      observer.dispose(); 
     } 

     singleStream.subscribeOn(...) 
      .observerOn(...) 
      .subscribeWith(observer); 
    } 
} 

當我執行上面的代碼中,ProtocolViolationException不再拋出,我能夠從單個流獲得成功的事件。但是當我幾次嘗試撥打doSomeStuff()方法時,它在首次通話中成功完成,但在第二次通話時沒有發出任何事件。我能夠確認訂閱通過doOnSubscribe()兩次都發生,但單次數據流的代碼發送事件從未在第二次調用中執行。所以我有三個問題:

  1. 爲什麼ProtocolViolationException首先被拋出?
  2. 爲什麼我能夠在第一次訂閱時獲得該事件,而不是在第二次訂閱上,即使我們在這兩種情況下都訂閱了源代碼?
  3. 如何通過只使用一個實例重複觀察者?

回答

1

1)您不允許重複使用DisposableSingleObserver及其堂兄弟,因爲它們是有狀態的且僅限一次使用。這是由於Single規定的協議:正好一個onSubscribe,最多一個onSuccessonError。第二次訂閱違反了此協議。

2)處置DisposableSingleObserver將其置於處置狀態,任何後續訂閱嘗試將被視爲立即處置。

3)你不應該。爲什麼要多次訂閱,爲什麼不能每次都使用新的DisposableSingleObserver。你應該重新考慮你的數據流。

+0

對於'DisposableObserver',1&2也是正確的嗎?關於3,我試圖限制觀察者的實例數量。 – Harry

+0

我把那些人稱爲「其堂兄弟」是的。 – akarnokd