У меня есть Button
, из которого я создаю Observable<OnClickEvent>
.RxAndroid ViewObservable NetworkOnMainThreadException
Когда кнопка нажата, я хочу получить файл из сети, но у меня возникают проблемы с сетью и потоками.
Этот пример бросает android.os.NetworkOnMainThreadException
:
Observable<OnClickEvent> networkButtonObservable = ViewObservable.clicks(testNetworkButton);
networkButtonObservable
.map(new Func1<OnClickEvent, List<String>>() {
@Override
public List<String> call(OnClickEvent onClickEvent) {
return TestAPI.getTestService().fetchTestResponse();
}
}
)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Object>() {
@Override
public void call(Object o) {Log.w("Final result: " + o);
}
}
);
Так что я стараюсь из другого потока.
Следующие броски rx.exceptions.OnErrorNotImplementedException: Observers must subscribe from the main UI thread, but was Thread[RxNewThreadScheduler-1,5,main]
:
networkButtonObservable
.subscribeOn(Schedulers.newThread())
.map(new Func1<OnClickEvent, List<String>>() {
@Override
public List<String> call(OnClickEvent onClickEvent) {
return TestAPI.getTestService().fetchTestResponse();
}
}
)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Object>() {
@Override
public void call(Object o) {Log.w("Final result: " + o);
}
}
);
Ok .. Теперь я стараюсь с .debounce()
в начале:
networkButtonObservable
.debounce(10, TimeUnit.MILLISECONDS)
.map(new Func1<OnClickEvent, List<String>>() {
@Override
public List<String> call(OnClickEvent onClickEvent) {
return TestAPI.getTestService().fetchTestResponse();
}
}
)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Object>() {
@Override
public void call(Object o) {Log.w("Final result: " + o);
}
}
);
И это удается.
Очевидно, что я не люблю добавлять задержки в свой код, поэтому я пытаюсь выяснить, что происходит, по-нити. Почему первый пример не выполняет код внутри .map()
в фоновом потоке?
Или что мне здесь не хватает?
--- Обновление
я изменить TestApi вернуть наблюдаемый и изменить первый вызов в networkButtonObservable к .flatMap()
. Это также работает правильно. Но я до сих пор не знаю, почему исходный способ использования .map()
должен завершиться неудачей.
networkButtonObservable
.flatMap(new Func1<OnClickEvent, Observable<?>>() {
@Override
public Observable<?> call(OnClickEvent onClickEvent) {
return TestAPI.getTestService().fetchTestResponseObservable();
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Object>() {
@Override
public void call(Object o) {Log.w("Final result: " + o);
}
}
);
Как и ошибка, вы не можете запустить сетевую операцию в потоке пользовательского интерфейса. – Carnal
Какая строка выбрасывает это исключение: «Наблюдатели должны подписываться из основного потока пользовательского интерфейса, но были ...»? Я думаю, что вы подписываетесь на свой Observable в другом потоке, который представляет собой поток пользовательского интерфейса. (Но я не shure) – dwursteisen
'.subscribeOn (Schedulers.io())' должен идти после вашей карты, так как функция на карте вызывается при подписке – njzk2