发现了一个奇怪的情况,我在fragment初始化的时候,new了一个子线程。然后在子线程设置了一个textView的字符串,并且设置了ta的click监听事件
@Override
protected void init() {
LogUtils.dThread("<<<<>>>>>");
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("<<<<<>>>>>");
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方法检查当前线程。
Android的setXXXClickListener只是一个监听器的事件,回调是你触摸屏幕的时候产生的。
之前一直把setXXXClickListener误认为是回调!导致子线程设置了click事件还有效果,把自己搞晕了。其实是正确的流程,没啥问题!