android 執行緒更新UI的問題
阿新 • • 發佈:2022-04-13
子執行緒更新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由它例項化.只屬於根佈局的.