原理分析:
从ActivityThread使用Handler的情况来进行分析,在入口main方法中可以看到,首先调用
prepareMainLooper()方法,其中调用了prepare()方法,该方法会通过new Looper()来创建looper对象,当重复调用prepare()方法时会抛出异常,该对象保存在ThreadLocal中,这就确保了每个线程只有一个looper对象,在new Looper()方法中会创建final对象MessageQueue,确保一个looper对象中只有一个MessageQueue;
然后MessageQueue在创建过程中通过调用jni方法
nativeInit()
创建Native的消息队列NativeMessageQueue,并返回一个long型变量用于存储
NativeMessageQueue信息
,通过该变量java和native建立的连接,再看Native Looper的构造方法中首先创建用于唤醒的文件描述符mWakeEventFd,然后调用epoll_create方法创建epoll对象,继而将epoll_ctl方法将mWakeEventFd加入到epoll的监控中;
在Main方法的最后,调用了Looper.loop()方法,loop()方法内会看到一个无限for循环,这时候就会有人问为什么无限for循环没到导致主线程卡死或者出现ANR呢,它的关键就在后面调用queue.next()方法来取Message,next()方法中会调用
nativePollOnce()方法,这是NativeMessageQueue的方法,里面会调用Looper的pollOnce()方法,最终会调用epoll_wait方法,这是一个阻塞方法,使方法不再进行,释放cpu,线程进入等待队列。这也就解释了为什么线程不会被卡死。那什么时候会被唤醒呢,这就引出了Handler,在ActivityThread中H内部类继承了Handler,里面承载了所有四大组件的生命周期调用。当需要启动Activity时,ApplicationThread通过handler.sendMessage()方法将msg.what为LUNCHE_ACTIVITY的message加入到
MessageQueue中,
MessageQueue
是按照Message触发时间的先后顺序排列的,队头的消息是将要最早触发的消息。当有消息需要加入消息队列时,会从队列头开始遍历,直到找到消息应该插入的合适位置,以保证所有消息的时间顺序。
调用到MessageQueue的enqueueMessage()方法,
最后会调用
nativeWake()方法,最终调用Native Looper的wake()方法,该方法中会向mWakeEventFd中写入字符1,这时epoll会监测到被监控的文件描述符发生了变化,唤醒等待中的线程,使线程进入运行状态,这时MessageQueue的next()方法会继续向下运行,来查找满足条件的Message并返回到Looper.loop()的循环体中,再交由msg的target进一步分发,在ActivityThread的内部类H中的handMessage中根据不同的msg.what来处理不同方法调用,至此一次消息处理完毕,Looper.loop()再次进入循环模式,重复前面的动作。
![](https://img-blog.csdnimg.cn/20201217180024445.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hlbGxvbG9uZXdvbGY=,size_16,color_FFFFFF,t_70)