Handler机制部分核心分析(知道这么多其实也够了,不需要每行代码搞懂)
基本涉及: Looper MessageQueue Message
在日常开发中,我们使用Handler比较多,所以Handler也是成为安卓人的宠儿以及面试官的宠儿;那么我们今天就仔细聊聊Handler机制,剖析剖析他玩玩;
其实我们Android程序其实就是消息驱动的。在APP 启动中,都有一个主入口:
对于Android 的程序主入口就是**ActitivtyThread** 类的main函数:
所以从主入口可以看出:Android 程序的运行其实就是消息驱动的进程。
好,分析源码可以看出:主线程的Looper随着程序的启动,已经创建出来了。
从Looper的初始化中可以看出,一个线程只能有一个Looper,不然抛异常;
从上述代码块可以知道,new 了一个Looper 的实例出来,并set到sThreadLocal;继续看Looper的构造函数:
细心地同学看到了有个boolean入参数,关于这个参数后续再说是什么意思;在这个Looper的构造方法里面,Looper创建的MessageQueue,
同是获取当前线程对象;
我们看下Looer.loop():
从Loop.loop()源码分析。因为源码很长,所以筛检我们需要分析的,可以看出是一个无限循环开启:for(,),MessageQueue不断取出队列里的消息通过 queue.next(); 如果有消息,就交给 msg.target 去处理。其实这个msg.target就是Handler; 所以可以这么说 Handler就是用来发送消息和处理消息的一个类。好我们分析下
queue.next()的源码,他内部其实也是个死循坏;
从上述代码分析;主分析:获取当前时间,然后拿当前消息的时间与消息执行处理的时间做差值(msg.when 代表的就是发送消息时候带进去的(当时time+deday,deday代表延迟多长时间))。如果小于当前时间就从链表头取出来,移除同时返回msg,(Messagequeue是单向链表结构,它里面的存的时间都是按照时间的从小到大入列);当msg==null,说明当前队列没有msg,设置等待时间-1(代表无线等待).直到enqueueMessage的nativeWake来唤醒。
继续:说到取到消息后handler怎么处理消息的:请看源码:
handler通过上述代码进行消息的处理。有个判断可以分析下:
第一个判断msg.callback!=null。 说明发送消息的时候传入了一个runable 对象给了当前的消息进去。 通常就是我们用的post方式发送消息。其实post 和send 发送没有本质区别,都是将消息发送到消息队列里。
继续分析以上行为:其实就是个提供一个方法回调,我们在这里处理对应的消息行为就好(大部分做跟ui相关的逻辑处理啦);
见图: 有些面试题就会问:其实就可以分析为什么可以做到异步工作线程发送消息,消息的处理在主线程里了。其实用到了一个接口回调的原理。
什么是接口回调?可能大部分都懂,不懂的初学者就留给你们自己去了解啦,我在就不解释了。算是抛出一个课后小作业吧。
大家如果想讨论Handler,可以关注我,随时欢迎。后续会继续拆分一些细节小东西分解讲解;