尽管正确调用了observeOn(io线程),但RxJava NetworkOnMainThreadException

Posted

技术标签:

【中文标题】尽管正确调用了observeOn(io线程),但RxJava NetworkOnMainThreadException【英文标题】:RxJava NetworkOnMainThreadException despite correctly calling observeOn(io thread) 【发布时间】:2021-01-29 13:20:39 【问题描述】:

这里是代码

        getCompositeDisposable().add(Single.fromCallable(new Callable<Boolean>() 
                @Override
                public Boolean call() throws Exception 
                    URL url = new URL(pageUrl);
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                    int code = connection.getResponseCode(); // <- crashes here
                    return code == 200;
                
            )
                    .observeOn(getSchedulerProvider().io())
                    .subscribeOn(getSchedulerProvider().ui())
                    .subscribe((pageAvailable) -> 
                        boolean useCache = !pageAvailable;
                        getMvpView().loadPage(useCache, pageUrl);
                    , Timber::e)
    );

无法理解这里有什么问题。网络代码应该在 io 线程上运行,然后将结果返回给 ui 线程。这段代码甚至可以在 io 线程上运行吗?我很困惑。

【问题讨论】:

这不正确......我认为你应该使用Single.defer然后在io上sunbscribe然后在ui上观察......所以这是完全错误的 【参考方案1】:

尽管正确调用了 observeOn(io 线程)

不正确,您的代码应该是:

  .subscribeOn(getSchedulerProvider().io()) //do work on the io thread
  .observeOn(getSchedulerProvider().ui()) //apply changes to ui thread

永远记住subscribeOn 是您工作的地方,order does matter

【讨论】:

“永远记住 subscribeOn 是你将要做工作的地方..” - 这适用于冷 obervables,但是订阅线程对上游发布者的线程没有影响的热 observables - 你会在发布者线程的下游接收这些排放,除非您使用 observeOn 进行更改 - 了解这些差异很重要。

以上是关于尽管正确调用了observeOn(io线程),但RxJava NetworkOnMainThreadException的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 RxKotlin 'observeOn' 主线程

尽管函数调用的参数数量不正确,但 C 程序编译

尽管 PList 设置正确,但状态栏仍出现在 iOS 7 中

RxJava2探索-线程切换原理之observeOn

RxJava2探索-线程切换原理之observeOn

Rxjava observeOn()和subscribeOn()初探