RxJava observeOn 似乎无法正常工作
RxJava observeOn seems to be not work correctly
我正面临来自 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 “Only the original thread that created a view hierarchy can touch its views.”" 的答案,解决方案是 运行 在 MainThread 上,但这里实际上是 运行 在 MainThread
上
[编辑]
问题是操作员的命令,所以
将 doAfterNext 替换为 observeOn.
正如@fraggjkee 和@EpicPandaForce 已经提到的,问题就在这里:
(application as? App)?.relayPages
?.doAfterNext{
hideLoading()
}
What is the problem:
Android “Only the original thread that created a view hierarchy can touch its views
当有人试图从非 UI 线程更新 UI 状态时,就会出现此问题。 UI-eventloop 是单线程的。因此禁止其他线程更新 UI-状态(例如查看属性等)
Why is observeOn not working?
(application as? App)?.relayPages
?.doAfterNext{
hideLoading()
}
?.observeOn(AndroidSchedulers.mainThread())
ObserveOn 在 observable 中将线程从一个运算符切换到另一个运算符。当 relayPages 发出一个值时,它将在任何给定线程上通过 doAfterNext 传递,很可能是订阅线程。通过 doAfterNext 之后,退出将通过 ObserveOn 操作符。这就是魔法发生的地方。在此运算符中,emit (onNext) 操作将在 UI-eventloop (AndroidSchedulers#mainThread).
中作为可运行项排队。
如需进一步说明,请查看此说明:http://tomstechnicalblog.blogspot.de/2016/02/rxjava-understanding-observeon-and.html
Problem
#doAfterNext 运算符是从非 UI 线程调用的,它试图更改某些 UI 状态。
Resolution
所有 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()
}
Summary
ObserveOn 必须放在运算符链中,在 UI 状态更改之前。
我正面临来自 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 “Only the original thread that created a view hierarchy can touch its views.”" 的答案,解决方案是 运行 在 MainThread 上,但这里实际上是 运行 在 MainThread
上[编辑] 问题是操作员的命令,所以 将 doAfterNext 替换为 observeOn.
正如@fraggjkee 和@EpicPandaForce 已经提到的,问题就在这里:
(application as? App)?.relayPages
?.doAfterNext{
hideLoading()
}
What is the problem: Android “Only the original thread that created a view hierarchy can touch its views
当有人试图从非 UI 线程更新 UI 状态时,就会出现此问题。 UI-eventloop 是单线程的。因此禁止其他线程更新 UI-状态(例如查看属性等)
Why is observeOn not working?
(application as? App)?.relayPages
?.doAfterNext{
hideLoading()
}
?.observeOn(AndroidSchedulers.mainThread())
ObserveOn 在 observable 中将线程从一个运算符切换到另一个运算符。当 relayPages 发出一个值时,它将在任何给定线程上通过 doAfterNext 传递,很可能是订阅线程。通过 doAfterNext 之后,退出将通过 ObserveOn 操作符。这就是魔法发生的地方。在此运算符中,emit (onNext) 操作将在 UI-eventloop (AndroidSchedulers#mainThread).
中作为可运行项排队。如需进一步说明,请查看此说明:http://tomstechnicalblog.blogspot.de/2016/02/rxjava-understanding-observeon-and.html
Problem
#doAfterNext 运算符是从非 UI 线程调用的,它试图更改某些 UI 状态。
Resolution
所有 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()
}
Summary
ObserveOn 必须放在运算符链中,在 UI 状态更改之前。