我正面临来自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上运行
[编辑] 问题是操作员的命令,所以 将 doAfterNext 替换为 observeOn 。
答案 0 :(得分: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
问题
从非UI线程调用#doAfterNext运算符,该非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()
}
摘要
在更改UI状态之前,ObserveOn必须放置在操作员链中。