1. 程式人生 > 其它 >android 執行緒更新UI的問題

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由它例項化.只屬於根佈局的.