我有一个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所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)