Mam dziwny problem w jednym z moich działań. Po powrocie z robienia zdjęcia/wideo w moim onActivityResult
wyświetlam okno dialogowe, które pozwala użytkownikowi nazwać kamerę. Po naciśnięciu przycisku OK, wysyłam onNext()
do tematu z żądaną nazwą pliku, który kopiuje plik (i pokazuje okno dialogowe postępu).Obserwowalne działa na głównym wątku, mimo że subscribeOn() jest wywoływana w innym wątku
Z jakiegoś powodu funkcja map()
, która wykonuje kopię, jest zawsze wywoływana w głównym wątku, mimo że nazywam ją subscribeOn(Schedulers.io())
.
@Override
protected void onActivityResult(final int requestCode, int resultCode, Intent intent) {
...
final PublishSubject<String> subject = PublishSubject.create();`
mSubscription = subject
.subscribeOn(Schedulers.io())
.map(new Func1<String, String>() {
@Override
public String call(String fileName) {
Log.I.d(TAG,"map");
return doSomeIOHeavyFuncition();
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<String>() {
@Override
public void call(final String fullPath) {
Log.d(TAG,"onNext");
doSomethingOnUI(fullPath);
subject.onCompleted();
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
...
}
}, new Action0() {
@Override
public void call() {
...
}
});
final AlertDialog dialog = new AlertDialog.Builder
....
.create()
.show();
dialog.getButton(DialogInterface.BUTTON_POSITIVE)
.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String someString = getStringFromDialog(dialog);
dialog.dismiss();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(input.getWindowToken(), 0);
showProgressDialog();
subject.onNext(someString);
}
});
}
Zmiana subscribeOn(Schedulers.io())
wezwanie do observeOn(Schedulers.io())
rozwiązać ten problem. Nadal chciałbym wiedzieć, dlaczego to nie działa ...
To coś nowego dla mnie. Używając RxJava przez jakiś czas byłem pewien, że wątek 'subscribeOn' dotyczy wszystkich operatorów niższego rzędu do pierwszego' observeOn' lub operatora z określonym harmonogramem. Czy to nie prawda? W takim przypadku jaka jest reguła wyboru wątku po 'subscribeOn'? – AndroidEx
Efekt "subscribeOn" idzie w górę i w dół do źródła zdarzeń. Pomyśl o tym w ten sposób. masz źródło, ale chcesz zasubskrybować go w innym wątku. Napisałeś 'new Thread (() -> source.subscribe (s)). Start();'. Coś takiego dzieje się w 'subscribeOn'. Wybrałeś harmonogram na podstawie tego, co się stanie, gdy zasubskrybujesz to źródło. Jeśli natychmiast otworzy połączenie sieciowe lub rozpocznie czytanie długiego pliku, przejdziesz do 'Schedulers.io()'. Jeśli coś zaczyna się mocno kompresować, robisz 'computation()'. – akarnokd
Dziękuję. Chociaż bardziej interesowało mnie to, co dzieje się po zasubskrybowaniu, w jakim wątku jest stosowany następny operator. Od twoich słów mam wrażenie, że nie ma gwarancji, że będzie to wątek określony w subskrybowaniu. – AndroidEx