2016-03-22 17 views
0

CODERxAndroid Intervall mit FlatMap Lockruf zweimal statt einmal

heartBeatSub = Observable.interval(HEARTBEAT_INTERVAL, TimeUnit.SECONDS) 
      .flatMap(new Func1<Long, Observable<Notification<Response>>>() { 
       @Override 
       public Observable<Notification<Response>> call(Long aLong) { 
        return api.requestHeartBeat(vehicleId).materialize(); 
       } 
      }) 
      .subscribeOn(Schedulers.io()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new Action1<Notification<Response>>() { 
       @Override 
       public void call(Notification<Response> responseNotification) { 
        Log.i("HEARTBEAT_INTERVAL", "Response from HEARTBEAT"); 
       } 
      }, new Action1<Throwable>() { 
       @Override 
       public void call(Throwable throwable) { 
        // TODO: 22/03/16 ADD ERROR HANDLING 
       } 
      }); 

PROBLEM

Meine call Methode wird zweimal statt ausgelöst einmal pro Intervall.

03-22 11:57:47.236 28078-28078/com.app I/HEARTBEAT_INTERVAL: Response from HEARTBEAT 
03-22 11:57:47.876 28078-28078/com.app I/HEARTBEAT_INTERVAL: Response from HEARTBEAT 

erste, den ich CARRING: Method threw 'java.lang.NullPointerException' exception. Cannot evaluate rx.Notification.toString() Und onNext genannt wird.

Zweite ist normal Response. Und wird onCompleted genannt

======== FIXED CODE ==========

Mit @ Daniel Lew Hilfe ich meinen Code festgelegt und arbeiten jetzt ist es richtig

private void triggerHeartBeat(final String vehicleId) { 
    heartBeatSub = Observable.interval(HEARTBEAT_INTERVAL, TimeUnit.MINUTES) 
      .flatMap(new Func1<Long, Observable<Response>>() { 
       @Override 
       public Observable<Response> call(Long aLong) { 
        return api.requestHeartBeat(vehicleId); 
       } 
      }) 
      .subscribeOn(Schedulers.io()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new Action1<Response>() { 
       @Override 
       public void call(Response response) { 
        Log.i("HEARTBEAT_INTERVAL", "Response from HEARTBEAT"); 
       } 
      }, new Action1<Throwable>() { 
       @Override 
       public void call(Throwable throwable) { 
        // TODO: 22/03/16 ADD ERROR HANDLING 
       } 
      }); 
+0

Was versuchen Sie hier mit 'materialize' zu ​​erreichen? Zwei Ereignisse scheinen mir gut zu sein: ein "onNext" -Ereignis und ein "onCompleted", was gibt es nach "materialize" noch zu erwarten? – AndroidEx

Antwort

4

Sie sollten materialize() nicht anrufen. Es hebt alle Benachrichtigungen (onNext(), onCompleted() und onError()) in ihre eigenen onNext() Aufrufe, mit negativen Auswirkungen hier.

Jede API-Anforderung innerhalb des flatMap() ist ein komplettes Observable, was bedeutet, dass sie sowohl Anrufe onNext(response) und onCompleted(). Normalerweise würde flatMap() nicht weiterleiten onCompleted() (seit interval() ist noch nicht abgeschlossen), aber seit Sie materialize() anrufen, werden alle Benachrichtigungen an den Abonnenten weitergeleitet.

Mit anderen Worten, Sie sind diese bekommen:

  1. -Mitteilung (von OnNext (mit Response))
  2. -Mitteilung (von OnCompleted)

Wenn Sie nicht verwendet haben materialize() würden Sie bekommen, was Sie wollen:

  1. OnNext (mit Response).
+1

Vielen Dank Kumpel, dass mein Problem behoben. Auch danke für die Erklärung des Problems, sieht aus, als ob ich 'materialize()' nicht richtig verstanden habe. – JakubW

Verwandte Themen