子線程居然可以更新UI!

一、子線程更新了UI

發現了一個奇怪的情況,我在fragment初始化的時候,new了一個子線程。然後在子線程設置了一個textView的字符串,並且設置了ta的click監聽事件

@Override
    protected void init() {
        LogUtils.dThread("<<<<<init>>>>>>");
        testBtn = (TextView)getActivity().findViewById(R.id.test);

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(2000);
                }catch (Exception e){
                    e.printStackTrace();
                }
                LogUtils.dThread("<<<<<<run>>>>>>");
                testMethod();
            }
        }).start();
    }

    private void testMethod(){
//        testBtn.setText("test更改1");
        testBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                LogUtils.dThread("testMethod>>onClick");
                testBtn.setText("test更改");
            }
        });
    }

init()是fragment初始化加載的方法,註釋掉的

//        testBtn.setText("test更改1");

是UI刷新。

之前沒有加Thead.sleep(20000);發現更新了UI!

之後加了就好了。

原因參考博文:https://www.jianshu.com/p/29e75093f5a2

大致意思爲:

ViewRootImpl的創建在onResume方法回調之後,而我們一開篇是在onCreate方法中創建了子線程並訪問UI,在那個時刻,ViewRootImpl是沒有創建的,無法檢測當前線程是否是UI線程,所以程序沒有崩潰一樣能跑起來,而之後修改了程序,讓線程休眠了200毫秒後,程序就崩了。很明顯200毫秒後ViewRootImpl已經創建了,可以執行checkThread方法檢查當前線程。

二、Click事件

Android的setXXXClickListener只是一個監聽器的事件,回調是你觸摸屏幕的時候產生的。

之前一直把setXXXClickListener誤認爲是回調!導致子線程設置了click事件還有效果,把自己搞暈了。其實是正確的流程,沒啥問題!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章