2016-05-14 3 views
0

Ich verwende RxAndroid, um ein paar Sachen im Hintergrund zu tun. Dies ist mein Code:RxAndroid und Multithreading

Observable<MyClass[]> observable = Observable.create(new Observable.OnSubscribe<MyClass[]>() { 

     @Override 
     public void call(Subscriber<? super MyClass[]> subscriber) { 
       System.out.println(Looper.myLooper() + " - " + Looper.getMainLooper()); 
       try { 
        MyObject myObject = ... 
        //do the background work 
        subscriber.onNext(myObject); 
        subscriber.onCompleted(); 
       } catch (Exception e) { 
        subscriber.onError(e); 
        e.printStackTrace(); 
       } 
      } 
     }); 

     observable.subscribeOn(Schedulers.newThread()) 
        .observeOn(AndroidSchedulers.mainThread()) 
        .subscribe(new Action1<MyClass[]>() { 
         @Override 
         public void call(MyClass[] myObjects) { 
          //do work on the ui Thread 
         } 
        } 
     ); 

Dies ist mein erstes Mal mit RxAndroid/RxJava/Looper.myLooper()/Looper.getMainLooper()

Von dem, was ich höre, Looper.myLooper() gibt Ihnen den Namen ID des Threads der aktuelle Code läuft auf und Looper.getMainLooper() gibt Ihnen die ID des Hauptfadens. Wenn ich die App in der SysOut ausführen, druckt es die gleiche ID für beide aus.

Mache ich etwas falsch oder verkenne ich die 2 Looper-Funktionen?

Antwort

2

Es wird empfohlen, dass Sie Observable.create nicht verwenden, außer Sie wirklich wissen, was Sie mit Observables tun. Es gibt viele Dinge, die Sie möglicherweise falsch machen können.

Der Grund dafür, dass Ihr Code innerhalb Ihres Create auf dem Hauptthread ausgeführt wird, ist, dass er aufgerufen wird, wenn das Observable nicht erstellt wird, wenn Sie es abonnieren.

Für das, was Sie versuchen zu erreichen, ich Observable.defer Vom docs verwenden würde:

Das Aufschieben Operator wartet, bis ein Beobachter abonniert hat, und dann erzeugt er einen beobachtbaren, in der Regel mit einer beobachtbaren Fabrik-Funktion.

Der Code würde wie etwas aussehen:

Observable<MyObject> observable = Observable.defer(new Func0<Observable<MyObject>>() { 
    @Override 
    public Observable<MyObject> call() { 

     System.out.println(Looper.myLooper() + " - " + Looper.getMainLooper()); 

     try { 
      MyObject myObject = new MyObject(); 
      return Observable.just(myObject); 
     } 
     catch (Exception e) { 
      return Observable.error(e); 
     } 

    } 
}); 

Subscription s = observable 
     .subscribeOn(Schedulers.newThread()) 
     .observeOn(AndroidSchedulers.mainThread()) 
     .subscribe(
       new Action1<MyObject>() { 
        @Override 
        public void call(MyObject myObject) { 

        } 
       }, 
       new Action1<Throwable>() { 
        @Override 
        public void call(Throwable throwable) { 
         throwable.printStackTrace(); 
        } 
       } 
     ); 

Jetzt in Ihrem logcat

erhalten Sie:

I/System.out: null - Looper (main, tid 1) {5282c4e0} 

Der Grund für die Looper.myLooper() Funktion null zurückgibt, ist, dass, wenn Sie einen neuen Thread Wenn Sie nicht Looper.prepare() anrufen, hat der Thread keinen Looper. Im Allgemeinen benötigen Sie keinen Looper für einen Thread, es sei denn, Sie möchten trotzdem einen Runnable dazu posten.

+0

Hey. Es tut uns leid. War für eine Weile weg. Ich werde das heute Abend ausprobieren und zurück zu dir :) –