关于在子线程中更新UI问题
来源:7-1 Android 中为什么非 UI 线程不能更新 UI?

用户1148542
2019-07-04
new Thread(){
@Override
public void run() {
super.run();
SystemClock.sleep(1000);
tv.setText(“更新了”);
}
}.start();
老师问下这个为啥不报错,TextView 的setText()方法最终会到ViewRootImpl 中的
@Override
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
checkThread();
mLayoutRequested = true;
scheduleTraversals();
}
}
然后checkThread()方法
void checkThread() {
if (mThread != Thread.currentThread()) {
throw new CalledFromWrongThreadException(
“Only the original thread that created a view hierarchy can touch its views.”);
}
}
这个获取的Thread并不是UI线程
4回答
-
jthou
2024-03-14
viewRootImpl在哪个线程创建的,后续的UI更新就需要在哪个线程执行,跟是不是UI线程没有强关系
00 -
慕运维4183363
2022-02-09
如果你的textView设置的是固定大小(具体数值,或者宽度不是wrap_content,settext之后高度没有变化)并且开启了硬件加速(默认就是开启的),源码里面分析最终会调用ViewRootImpl的invalidate()里面没有对线程进行检查,
所以没有崩溃。你把硬件加速关闭或者把textview的宽度设置成wrap_content就会崩溃。
00 -
用户1148542
提问者
2019-07-04
谢谢老师的解答
00 -
bennyhuo
2019-07-04
这个印象中之前我也遇到过,可能恰好没有走到这个分支,例如从你贴的代码来看 mHandlingLayoutInLayoutRequest 为 false 的话,似乎就不会走了,这块儿可能得确认下,也许如果新设置的文字不影响 TextView 的尺寸,就不需要 layout 了,这时候应该不会重新出发 layout 吧~
00
相似问题