2015-12-15 19 views
5

Ich verwende ein RxAndroid observable, um einige Objekte (String in diesem Fall) abzurufen. Mein Service sieht wie folgt aus:Verwendungsplanung mit RxAndroid

public Observable<String> getRandomString() { 
    return Observable.create(new Observable.OnSubscribe<String>() { 
     @Override 
     public void call(Subscriber<? super String> subscriber) { 

      //code to retrieve result 

      subscriber.onNext("this is a string"); 
      subscriber.onCompleted(); 

     } 
    }); 
} 

ich in meinem Moderator abonnieren und poste das Ergebnis der Ansicht:

public void loadRandomString() { 

    Observable<String> observable = mService.getRandomString(); 
    observable 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribeOn(Schedulers.newThread()) 
      .subscribe(new Subscriber<String>() { 
       @Override 
       public void onCompleted() { } 

       @Override 
       public void onError(Throwable e) { 
        mMainView.onError(e.getLocalizedMessage()); 
       } 

       @Override 
       public void onNext(String string) { 

        //do something with string 
       } 
      }); 
} 

Dies funktioniert gut, und alle, aber ich möchte diese Operation regelmäßig sein (alle x Protokoll). Ich könnte eine Timer oder ScheduledThreadPoolExecutor verwenden, um dies immer wieder zu tun, aber ich würde gerne sehen, ob es eine Lösung im Bereich von RxAndroid gibt. Ich habe einige alte Lösungen aus dem Jahr 2013 gefunden, aber eine Menge des Codes ist zu dieser Zeit veraltet. Ist dies mit einer Rekursion möglich, oder kann ich das eleganter erreichen?

Vielen Dank im Voraus!

+0

ist 'getRandomString' gleich wie 'getString'? – Blackbelt

+0

Ja! Ich habe aus Gründen der Einfachheit einige Namen geändert. –

Antwort

6

Was Sie wahrscheinlich wollen, ist Observable.interval(). Es emittiert in einem zeitlichen Intervall. Sie können dann flatmap, dass in Ihrem Observable<String>, etwa so:

Observable.interval(3, TimeUnit.MINUTES) 
    .flatMap(new Func1<Long, Observable<String>>() { 
     @Override 
     public Observable<String> call(Long ignore) { 
     return getRandomString(); 
     } 
    }) 
    .subscribe(...insert your subscriber here...); 

Das heißt - wenn du gehst, dies alle paar Minuten zu tun, könnten Sie besser dran sein Blick in AlarmManager oder JobScheduler, da die Chancen Benutzer wird sich nicht lange auf deine App konzentrieren.


Als Nebenwirkung, wäre es viel einfacher sein Observable.just("this is a string") als Observable.create() zu verwenden.

+0

Danke für Ihre Antwort, das scheint gut zu funktionieren! Ich habe es in 'Observable.interval (0, 3, TimeUnit.MINUTES)' geändert, weil ich die Verzögerung nicht am Anfang haben möchte. Danke für deinen Tipp zum 'AlarmManager', aber das ist nicht deine übliche App, der Anwendungsfall ist, dass die App tagelang im Vordergrund steht. Allerdings bin ich verwirrt über den "Observable.just()" -Teil, in meinem ursprünglichen Beitrag habe ich den gesamten relevanten Code entfernt und einfach einen Mock-String in die 'onNext()' eingefügt, sicherlich mit der ursprünglichen Logik 'Observable.just()' würde nicht ausreichen? –

+0

@NielsMasdorp In diesen Fällen verwende ich 'defer (() -> Observable.just())'. Auf diese Weise können Sie Code ausführen, bevor das Element ausgegeben wird. Das Problem bei der Verwendung von 'create()' ist, dass Sie (theoretisch) mit Anfragen und Gegendruck umgehen müssen und das ist ein echter Schmerz. –

Verwandte Themen