我正从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。
正如已经提到的@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状态之前放置在操作员链中。