2015-07-19 14 views
5

Stworzyłem prostą czynność z paskiem progów nieskończoności i próbuję uruchomić czasochłonną metodę używając RxJava, aby zapobiec blokowaniu wątku UI, ale każdy wątek UI jest zablokowany. Myślę, że moje rozwiązanie ma problem z emisją Observable. Czy ktoś może mi pomóc? Jestem początkującym w RX.AndroidRX - uruchom metodę w tle

public class MainActivity extends AppCompatActivity { 

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

public void doSomething(View view) { 
    doHeavyStuff() 
      .subscribeOn(Schedulers.newThread()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .doOnNext(new Action1() { 
       @Override 
       public void call(Object o) { 
        Toast.makeText(getApplicationContext(), "FINISHED", Toast.LENGTH_SHORT).show(); 
       } 
      }) 
      .subscribe(); 
} 

private Observable doHeavyStuff() { 
    for (int i = 0; i < 999999999; i++) { 
     for (int j = 0; j < 2; j++) { 
     } 
    } 
    return Observable.just(1); 

} 

Odpowiedz

8

Twój doHeavyStuff() wykonuje obliczenia na wywołanie wątku, wystarczy owinąć wynik się widoczne. W celu owijania obliczeń do zaobserwowania należy użyć odroczyć

Observable.defer(new Func0<Observable<Integer>>() { 
    @Override 
    public Observable<Integer> call() { 
     return Observable.just(doHeavyStuff()); 
    } 
}); 

następnie można określić wątki przez subscribeOn i observeOn metod

1

Ponadto, można użyć RxJavaAsyncUtil:

compile 'io.reactivex:rxjava-async-util:0.21.0' 

Kod:

Observable.fromFunc0(() -> doHeavyStuff()) 
7

Według docs

nieaktualne: fromFunc0 Niepotrzebne teraz, że Func0 rozciąga Callable. Po prostu wywołaj zCallable (java.util.concurrent.Callable).

Więc można wykonać połączenie w ten sposób:

Observable.fromCallable(new Callable<Object>() { 
      @Override 
      public Object call() throws Exception { 
       return someMethod(); 
      } 
     }).subscribeOn(Schedulers.io()) 
       .observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Object>() { 
        @Override 
        public void call(Object object) { 

        } 
       }); 
3

W RxJava2 możliwym rozwiązaniem jest:

Wersja z lambdas:

Single.fromCallable(() -> loadInBackground()) 
    .subscribeOn(Schedulers.io()) 
    .observeOn(AndroidSchedulers.mainThread()) 
    .subscribe((myObject) -> { updateUi(myObject) }); 

Wersja bez lambdas:

Single.fromCallable(new Callable<Object>() { 
    @Override 
    public Object call() throws Exception { 
     return loadInBackground(); 
    } 
}) 
.subscribeOn(Schedulers.io()) 
.observeOn(AndroidSchedulers.mainThread()) 
.subscribe(new Consumer<Object>() { 
    @Override 
    public void accept(Object myObject) throws Exception { 
     updateUi(myObject); 
    } 
}); 

przykład metody:

private Object loadInBackground() { 
    // some heavy load code 
    return myObject; 
} 

private void updateUi(Object myObject) { 
    // update your Views here 
}