RxAndroid ViewObservable NetworkOnMainThreadException

RxAndroid ViewObservable NetworkOnMainThreadException,第1张

概述我有一个Button,我从中创建一个Observable<OnClickEvent>.单击按钮时,我希望从网络中获取文件,但是我遇到了有关网络和线程的问题.此示例抛出android.os.NetworkOnMainThreadException:Observable<OnClickEvent>networkButtonObservable=ViewObservable.clicks(testNetworkB

我有一个button,我从中创建一个Observable< OnClickEvent>.

单击按钮时,我希望从网络中获取文件,但是我遇到了有关网络和线程的问题.

此示例抛出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:观察者必须从主UI线程订阅,但是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);                   }               }    );

好的..现在我尝试使用.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以返回一个Observable,并将第一次调用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);                   }               }    );

解决方法:

我不是AndroID的专家,但基于错误消息,我认为你需要在主线程和后台线程之间反d.通常,AndroID示例显示您在流处理中添加subscribeOn / observeOn对:

Observable.just(1).map(v -> dobackgrounDWork()).subscribeOn(Schedulers.io()).observeOn(AndroIDSchedulers.mainThread()).subscribe(v -> {});

但在这些情况下,“来源”通常是一种你可以控制的寒冷观察.

在您的问题中,源是一个热门的Observable,您需要在主线程上进行订阅,但是您需要在后台线程上进行网络调用,然后在主线程上显示结果.

在这种情况下,您可以多次使用observeOn:

networkbuttonObservable.subscribeOn(AndroIDSchedulers.mainThread()) // just in case.observeOn(Schedulers.io()).map(v -> TestAPI.getTestService().fetchTestResponse()).observeOn(AndroIDSchedulers.mainThread()).subscribe(v -> updateGUI(v));

我认为fetchTestResponSEObservable有自己的subscribeOn或observeOn应用于它,因此它不会抛出网络异常.

另外我想提一下,使用多个subscribeOn在功能上等同于仅使用最接近发射源的一个,但从技术上讲,它将占用未使用的线程资源.但是,在流中使用多个observeOn具有相关性,因为您可以有意义地“管道”线程之间的流处理.

总结

以上是内存溢出为你收集整理的RxAndroid ViewObservable NetworkOnMainThreadException全部内容,希望文章能够帮你解决RxAndroid ViewObservable NetworkOnMainThreadException所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1116155.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存