RxJava watchOn似乎无法正常工作

问题描述 投票:0回答:1

我正从RxJava遇到此错误

Android“只有创建视图层次结构的原始线程才能触摸其视图。”

我使用的代码

Log.d(TAG, "stratObserving:qw ${Thread.currentThread()}")
(application as? App)?.relayPages
                ?.doAfterNext{
                    hideLoading()
                }
                ?.observeOn(AndroidSchedulers.mainThread())
                ?.subscribe({
                   "data found ${it.size}".log()
                    pageAdapter.setPageList(it)
                    rvAyahsPages.scrollToPosition(pos)
                    "data pageAdapter ${pageAdapter.itemCount} , ${Thread.currentThread()}".log()
                    foundState()
                }, {
                    "error ${it.message}".log()
                })
                ?.addTo(model.bg)
 private fun foundState() {
        spShowAyahs?.visibility = View.GONE
        tvNoQuranData?.visibility = View.GONE
        rvAyahsPages?.visibility = View.VISIBLE
        "found $rvAyahsPages $spShowAyahs".log()
    }

但是

Log.d(TAG, "stratObserving:qw ${Thread.currentThread()}") 打印 Thread [main,5,main]

Log.d(TAG, "stratObserving:qw ${Thread.currentThread()}") 打印 Thread [main,5,main]

[注]

此问题不同于“ Android“只有创建视图层次结构的原始线程才能触摸其视图。””回答该解决方案是在MainThread上运行,但实际上它在MainThread上运行

[编辑]问题是操作员的命令,所以用observeOn替换doAfterNext

android multithreading rx-java2
1个回答
0
投票

正如已经提到的@fraggjkee和@EpicPandaForce,问题在这里:

(application as? App)?.relayPages
                ?.doAfterNext{
                    hideLoading()
                }

是什么问题:Android“只有创建视图层次结构的原始线程才能触摸其视图

[当有人尝试从非UI线程更新UI状态时,会出现此问题。 UI-eventloop是单线程的。因此,禁止其他线程更新UI状态(例如,视图属性等)

为什么observeOn不起作用?

(application as? App)?.relayPages
                ?.doAfterNext{
                    hideLoading()
                }
                ?.observeOn(AndroidSchedulers.mainThread())

ObserveOn在可观察范围内将线程从一个运算符切换到另一个运算符。当relayPages发出一个值时,它将在任何给定线程(很可能是订阅线程)上通过doAfterNext。通过doAfterNext之后,许可将通过ObserveOn-operator。这是魔术发生的地方。在此运算符中,emit(onNext)操作将作为可运行程序放入UI事件循环(AndroidSchedulers#mainThread)中。

有关更多说明,请查看以下说明:http://tomstechnicalblog.blogspot.de/2016/02/rxjava-understanding-observeon-and.html

问题

#doAfterNext运算符从非UI线程调用,该非UI线程试图更改某些UI状态。

解决方法

必须从UI线程调用所有UI状态更改。因此,您必须确保是这种情况。

(application as? App)?.relayPages
                // observeOn switches the thread from X to the UI-eventloop
                ?.observeOn(AndroidSchedulers.mainThread())
                // hideLoading is called from UI-eventloop, everything should be fine
                ?.doAfterNext{
                    hideLoading()
                }

摘要

ObserveOn必须在更改UI状态之前放置在操作员链中。

© www.soinside.com 2019 - 2024. All rights reserved.