一、子線程更新了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事件還有效果,把自己搞暈了。其實是正確的流程,沒啥問題!