2015-08-21 7 views
5

Rx Art, die Dinge für keine sehr komplex sein kann und aus vielen Gründen ... aber ich fühle mich gibt es einfache Möglichkeiten, einfache Dinge mit RX zu tun ...Wie würde ich diese Anweisung mit RxJava ausführen?

Wie würde ich einfach auf einem diese Anweisung ausführen Hintergrund-Thread und erhalten die Antwort auf den ui-Thread?

Alle Funktionen dieses Objekts müssen auf einem Hintergrundthread ausgeführt werden. Abrufen, setzen, löschen und löschen

String city = Paper.get("city"); 
+0

Ich nehme an, "Get" ist eine blockierende Funktion, die auf einem Hintergrund-Thread ausgeführt werden sollte? – njzk2

+0

ja ist es. Alle Funktionen dieses Objekts müssen vom ui thread ablaufen ... get, delete, put, clear. – sirvon

Antwort

5

das Basisobjekt in Rx ist Observable. Dieses Objekt umschließt normalerweise ein OnSubscribe Objekt, das einfach eine Erweiterung von Action1 ist, die einen Subscriber als Parameter verwendet.

Was alles, was bedeutet, dass Sie brauchen nur eine Klasse zu definieren, die Ihren Anruf wickelt und übergibt das Ergebnis an den Subscriber:

public class RxPaperGet implements Observable.OnSubscribe<String> { 
    @Override 
    public void call(Subscriber<? super String> t1) { 
     try { 
      t1.onNext(Paper.get("city")); 
     } catch (Throwable t) { 
      t1.onError(t); 
      return; 
     } 
     t1.onCompleted(); 
    } 
} 

Das ist ein einfaches Beispiel ist. Jetzt möchten Sie das umhüllen, so dass Sie jede Funktion aufrufen können, und nicht nur Paper.get("city"). Etwas wie https://github.com/ReactiveX/RxJavaAsyncUtil/blob/0.x/src/main/java/rx/util/async/operators/OperatorFromFunctionals.java#L44 tut das, indem es Ihnen erlaubt, einen beliebigen Callable zu übergeben.

die in Ihrem Fall würde implementieren, wie:

Observable<String> res = OperatorFromFunctionals.fromCallable(() -> Paper.get("city")); 

(Falls Sie sich fragen, diese java8 lambdas gebracht ist von retrolambda auf Android ganz schön den Detaillierungsgrad von Rx zu entfernen.)

Sobald Sie Ihre beobachtbare haben, können Sie sich darauf abonnieren und Ergebnisse erzielen. Um auf dem Hintergrund ausgeführt werden, und die Ergebnisse auf dem UI-Thread abrufen, würden Sie tun:

res.subscribeOn(Schedulers.io()) 
    .observeOn(AndroidSchedulers.mainThread()) 

AndroidSchedulers durch rx-android zur Verfügung gestellt.

.subscribe(city -> Log.d(TAG, city)); 

, dass ein Abonnement zurückgibt, was nützlich ist, wenn Sie es absagen müssen:

Dann können Sie einfach mit dem Ergebnis calledback werden.

Gesamt:

OperatorFromFunctionals.fromCallable(() -> Paper.get("city")) 
    .subscribeOn(Schedulers.io()) 
    .observeOn(AndroidSchedulers.mainThread()) 
    .subscribe(city -> Log.d(TAG, city)); 
+0

das ist eine tolle Erklärung! ty for ya time – sirvon

+0

Ich habe eine harte Zeit mit __OperatorFromFunktionals__ was ist der Import, um es in den Code zu bringen? Es ist in rot in Android Studio. Ich habe rxjava dep gelöst. – sirvon

+0

die Paket-IDs auf Maven sind auf der Homepage des Github-Projekts angegeben, oder Sie können einfach die Klasse in Ihrem Projekt – njzk2

0

EDIT: Das ist nicht richtig. Löscht die Antwort nicht, um die Kommentare beizubehalten.

Sehr einfaches Beispiel:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 


    getPaper() 
      .subscribeOn(Schedulers.newThread()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new Action1<String>() { 
       @Override 
       public void call(String s) { 
        Log.d("xxx", s); 
       } 
      }); 


} 

private Observable<String> getPaper() { 

    return Observable.just(Paper.get()); 
} 

wo Paper.get() eine Operation mit langer Laufzeit, die ein String zurückgibt. Überprüfen Sie die docs for Scheduler.

Vergessen Sie nicht, im Hauptthread zu beachten, wenn Sie die Benutzeroberfläche nach dem Empfang des Ergebnisses Ihrer Operation ändern möchten. Andernfalls erhalten Sie eine Ausnahme zum Ändern der Benutzeroberfläche außerhalb des UI-Threads.

+3

' Observable.just() 'wird auf dem UI-Thread ausgeführt. Sie müssen "Defer" verwenden, um die Erstellung bis zum Zeitpunkt des Abonnements zu verschieben. http://blog.danlew.net/2015/07/23/deferring-observable-code-until-subscription-in-rxjava/ – LordRaydenMK

+0

@LordRaydenMK Ich denke, dass Sie Dinge hier mischen. just() imho hat nichts mit dem Thread zu tun, auf dem die Operation ausgeführt wird, sondern eher, wenn es gestartet wird: just() startet den Vorgang, sobald das Observable erstellt wird, create() startet den Vorgang nur dann, wenn das Observable ist abonniert. Sollte hier keinen Unterschied machen, weil wir sofort abonnieren. Korrigieren Sie mich, wenn ich falsch liege. – FWeigl

+0

verdammt ich mag dieses einfache Beispiel auch. ty! und die nachfolgende Erklärung von nur vs erstellen – sirvon

Verwandte Themen