2016-11-10 64 views
0

我有一個ViewModel類,它暴露了PublishSubject活頁夾。PublishSubject訂閱者未收到活動

視圖模型

public class ViewModel { 

    private PublishSubject<ActionsEvent> binder = PublishSubject.create(); 
    private Service service = createService(); 

    @Override 
    public Observable<ActionsEvent> getBinder() { 
     return binder.doOnSubscribe(initialize()); 
    } 

    private Action0 initialize() { 
     return new Action0() { 
      @Override 
      public void call() { 
       service.getActions().subscribe(new Action1<Action>() { 
        @Override 
        public void call(Action action) { 
         Log.d(TAG, "So far, so good"); 
         binder.onNext(new ActionFetchedEvent(action)); 
        } 
       }); 
      } 
     }; 
    } 

} 

而在活動,它訂閱動作時每個事件被取出被執行。

活動

public class MyActivity extends Activity { 

    @Override 
    public void onCreate(Bundle savedInstance) { 
     //More code 
     viewModel.getBinder().subscribe(new Action1<ActionsEvent>() { 
      @Override 
      public void call(ActionsEvent event) { 
       Log.d(TAG, "This is not printed!!"); 
       paintActionInUserInterface(event.getAction()); 
      } 
     }); 
    } 
} 

服務

public interface ActionsService { 
    @GET("/actions") 
    Observable<Action> getActions(); //Performs an HTTP request with Retrofit 
} 

ActionFetchedEvent

public class ActionFetchedEvent implements ActionsEvent { 

    private Action action; 

    //getters and setters 

} 

但沒有按訂戶」 t接收事件。爲什麼?

+0

爲什麼你需要一個主題?你可以訂閱你的服務返回的'Observable'。 –

回答

1

這是因爲您沒有使用.create()工廠方法創建Subject,並且onSubscribe將在您的訂閱回調之前調用,所以您將訂閱太晚而錯過了該元素。如果您訂閱,您可以使用BahaviourSubject,它將重播最後一個元素。

請問您能告訴我們您想達到什麼目的,因爲我認爲您可以以更好的方式撰寫觀察報告,而不是訂閱和發佈onNext到主題。

請看看我的例子。我使用RxJava2作爲環境。

public class ViewModelTest { 
    class ActionsEvent { 
    } 

    class ActionFetchedEvent extends ActionsEvent { 
     public ActionFetchedEvent(ActionsEvent actionEvent) { 

     } 
    } 

    interface Service { 
     public Observable<ActionsEvent> getActions(); 
    } 

    class MyViewModel { 
     private BehaviorSubject<ActionsEvent> binder; 

     private Service service; 

     public MyViewModel(Service service) { 
      this.service = service; 
      this.binder = BehaviorSubject.create(); 
     } 

     public Observable<ActionsEvent> getBinder() { 
      return binder.doOnSubscribe(disposable -> { 
       service.getActions().subscribe(action -> { 
          binder.onNext(new ActionFetchedEvent(action)); 
         } 
       ); 
      }); 
     } 
    } 

    @Test 
    public void name() throws Exception { 
     Service mock = mock(Service.class); 

     MyViewModel viewModel = new MyViewModel(mock); 

     when(mock.getActions()).thenAnswer(invocation -> { 
      return Observable.just(new ActionsEvent()); 
     }); 

     TestObserver<ActionsEvent> test = viewModel.getBinder().test(); 

     test.assertValueCount(1); 
    } 
} 
+0

謝謝。我已經嘗試過它,但它有效,但是當我有2個事件時,用戶只收到最後一個。我應該使用ReplaySubject嗎?我只想爲從服務(http請求)中檢索的每個操作發出一個事件。訂閱者在UI中繪製每個動作(包含在事件中)。 –

+0

請更新您的問題,並詳細說明getActions的功能以及您要實現的功能。我無法正確理解正在發生的事情。另請提供有關getActions將發送多少項目以及getBinder應接收哪些訂閱者的信息。 –

+0

已編輯。我希望你能理解並感謝你的時間。 –