2016-11-10 5 views
0

Ich habe eine Klasse ViewModel, die einen PublishSubject Binder freilegt.PublishSubject-Abonnent empfängt keine Ereignisse

Ansichtsmodell

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)); 
        } 
       }); 
      } 
     }; 
    } 

} 

Und in der Aktivität, eine Aktion abonnieren ausgeführt werden, wenn jedes Ereignis abgerufen wird.

Aktivität

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()); 
      } 
     }); 
    } 
} 

Dienst

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 

} 

Aber Teilnehmer doesn‘ Ich empfange die Veranstaltung. Warum?

+0

Warum brauchen Sie überhaupt ein Thema? Sie können einfach die von Ihrem Dienst zurückgegebene "Beobachtbare" abonnieren. –

Antwort

1

es ist, weil Sie nicht erstellen ein Thema mit .create() factory-Methode, und onSubscribe wird vor dem Rückruf Ihres Abonnements aufgerufen werden, so dass Sie zu spät abonnieren und das Element verpassen. Sie können ein BahamiourSubject verwenden, das das letzte Element wiedergibt, wenn Sie sich anmelden.

Könnten Sie uns bitte sagen, was Sie erreichen möchten, weil ich denke, dass Sie die Observablen besser zusammenstellen könnten, als das Abonnieren und Posten von onNext auf das Thema.

Bitte schauen Sie sich mein Beispiel an. Ich benutze RxJava2 als Umgebung.

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

Danke. Ich habe es versucht und es funktioniert, aber wenn ich 2 Ereignisse habe, erhält der Abonnent nur den letzten. Soll ich stattdessen ReplaySubject verwenden? Ich möchte nur ein Ereignis pro Aktion aus dem Dienst (http-Anfrage) abgerufen werden. Der Abonnent zeichnet jede im Ereignis enthaltene Aktion in der Benutzeroberfläche auf. –

+0

Bitte aktualisieren Sie Ihre Frage mit einer detaillierten Erklärung, was getActions macht und was Sie erreichen wollen. Ich kann nicht richtig verstehen, was passiert. Bitte geben Sie auch Informationen darüber an, wie viele Artikel getActions senden würde und welche Abonnenten von getBinder erhalten sollen. –

+0

Bearbeitet. Ich hoffe du verstehst und danke für deine Zeit. –