Handler流程分析

原理分析:
从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()再次进入循环模式,重复前面的动作。
 
 
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值