子线程居然可以更新UI!

一、子线程更新了UI

发现了一个奇怪的情况,我在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方法检查当前线程。

二、Click事件

Android的setXXXClickListener只是一个监听器的事件,回调是你触摸屏幕的时候产生的。

之前一直把setXXXClickListener误认为是回调!导致子线程设置了click事件还有效果,把自己搞晕了。其实是正确的流程,没啥问题!

你可能感兴趣的:(android知识类)