你真的理解Handler,Looper,Thread吗?

之前一直以为Handler的handleMessage方法总是运行在主线程,归根到底还是没有真正理解Looper的创建过程。

那么问题来了,为什么我们默认创建的Handler会运行在主线程呢?

默认情况下,ActivityThread类为我们创建的了主线程的Looper和消息队列,所以当你创建Handler之后发送消息的时候,消息的轮询和handle都是在UI线程进行的。

关于ActivityThread:默认整个应用程序,都是通过ActivityThread类启动的,在ActivityThread类当中,负责创建我们所有的Activity,并回调每个Activity中的生命周期方法。在ActivityThread类中,默认会去创建一个线程,这个线程叫做main线程(主线程)。所有的应用程序,更新UI的操作,都是在这个main线程中进行的。

ActivityThread类为我们创建的了主线程的Looper(图1)

再看Looper类中的prepareMainLooper方法

初始化MainLooper(图2)

接下来看prepareMainLooper方法的第一行prepare(false)方法

创建主线程的Looper存入到TreadLocal中(图3)

 这里我们需要对ThreadLocal类进行一下解释,ThreadLocal在我们的线程当中用于去保存一些变量信息,默认情况下,创建一个与线程相关的一个对象,是通过threadLocal存储的,threadLocal有set和get方法,set是把变量设置到threadLocal当中 ,get方法是获取出来。因为当前线程是UI线程,默认情况下threadLocal是没有存储的,所以为null,所以不走if而是new Looper对象之后在存储。

再回到图2,看最后一行获取MainLooper。

获取当前线程(主线程)程创建的Looper(图4)

到此为什么我们默认创建的Handler会运行在主线程呢?已经基本明白,如果还不明白可以看看Looper的loop方法。

到这里还没结束,那么怎么在子线程初始化Handler呢?也就是handleMessage方法运行在子线程。

Handler mHandler;

new Thread(new Runnable() {

            @Override

            public void run() {

                Looper.prepare();//Looper初始化

                //Handler初始化 需要注意, Handler初始化传入Looper对象是子线程中缓存的Looper对象

                mHandler = new Handler(Looper.myLooper());

                Looper.loop();//死循环

                //注意: Looper.loop()之后的位置代码在Looper退出之前不会执行,(并非永远不执行)

            }

        }).start();

也可以调用Android系统的ThreadHandler实现,关于ThreadHandler本篇不做分析,感兴趣可以自己看看源码。

到此本文种重点也就结束了。总结一下:

Handler的handleMessage方法不一定在主线程,取决于Looper所在的线程。

你可能感兴趣的:(你真的理解Handler,Looper,Thread吗?)