android 线程更新UI的问题
子线程更新UI
大多数说法是子线程更新UI会出现 CalledFromWrongThreadException的异常,但在偶然情况下发现并不是这样.具体情况如下:
抛出异常的类和方法: ViewRootImpl:checkThread
ViewRootImpl.java
void checkThread() {
if (mThread != Thread.currentThread()) {
throw new CalledFromWrongThreadException(
"Only the original thread that created a view hierarchy can touch its views.");
}
}
此方法在ViewRootImpl中的RequestLayout方法中调用:
@Override
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
checkThread();
mLayoutRequested = true;
scheduleTraversals();
}
}
而ViewRootImpl会在onCreate方法之后初始化,所以在onCreate方法中立即开启主线程调用是不会出问题的,但如果线程sleep一段时间就会抛出异常:
new Thread(new Runnable() {
@Override
public void run() {
// try {
// Thread.sleep(3000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
tv_flextv1.setText("change thread");
// tv_flextv1.setBackgroundColor(getResources().getColor(R.color.design_default_color_primary));
}
}).start();
另一个证明的例子是如果在点击事件里面使用子线程更新UI会立即抛出异常.此外requestLayout方法调用的时机是布局大小改变,如果设置背景色等不会调用,由于setTest的控件是自适应大小的,所以会调用requestLayout.
ViewRootImpl 是View包括子类ViewGroup一些方法的具体实现,类接口ViewParent由它实例化.只属于根布局的.
吾生也有涯,而知也無涯。以有涯隨無涯,殆已
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步