1、前言
众所周知在Android中,子线程是不能更新UI的;
那么我在想,为什么不能,会产生什么问题;
是否真的就一定不能在子线程更新UI;
2、能否在子线程中更新UI
答案是可以的,比如以下代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = findViewById(R.id.tv);
new Thread(new Runnable() {
@Override
public void run() {
tv.setText("测试是否报出异常");
}
}).start();
}
运行结果并无异常,可以正常的在子线程中更新了TextView控件;假如让线程休眠1000ms,就会发生错误:
Only the original thread that created a view hierarchy can touch its views.
这句话的意思是只有创建视图层次结构的原始线程才能更新这个视图,也就是说只有主线程才有权力去更新UI,其他线程会直接抛异常的;
从at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:7905)的异常路径可以看到抛出异常的最终在ViewRootIml的checkThread方法里,ViewRootIml是View的根类,其控制着View的测量、绘制等操作,那么现在我们转到ViewRootImpl.java源码观察:
@Override
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
checkThread();
mLayoutRequested = true;
scheduleTraversals();
}
}
void che