关于在子线程中更新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线程没有强关系

0
0

慕运维4183363

2022-02-09

如果你的textView设置的是固定大小(具体数值,或者宽度不是wrap_content,settext之后高度没有变化)并且开启了硬件加速(默认就是开启的),源码里面分析最终会调用ViewRootImpl的invalidate()里面没有对线程进行检查,//img.mukewang.com/szimg/6203c014090041b307180263.jpg

所以没有崩溃。你把硬件加速关闭或者把textview的宽度设置成wrap_content就会崩溃。

0
0

用户1148542

提问者

2019-07-04

谢谢老师的解答

0
0

bennyhuo

2019-07-04

这个印象中之前我也遇到过,可能恰好没有走到这个分支,例如从你贴的代码来看 mHandlingLayoutInLayoutRequest 为 false 的话,似乎就不会走了,这块儿可能得确认下,也许如果新设置的文字不影响 TextView 的尺寸,就不需要 layout 了,这时候应该不会重新出发 layout 吧~

0
0

大厂资深面试官 带你破解Android高级面试

改变视野和思维 深度与广度兼备的 Android 进阶面试指导课程

1636 学习 · 222 问题

查看课程