1.android handler机制
handler机制,也就是android的异步消息处理机制。但是这个机制不仅仅是一个handler类来完成的。先总结性的给这个机制一些描述:
1.每个一线程持有有且只有一个消息队列,而且每一个线程持有且一个Looper循环器取消息
2.每个线程可以有多个hanlder实例,每个handler实例都可以往消息队列里发消息,handler可以处理自己发的消息或者一个Runnable对象。
3.handler与其发送的消息有绑定关系,消息队列里的消息是哪个handler发的,就由哪个handler处理。
4:如果一个handler在主线程创建,这个handler却可以在子线程发送消息到消息队列,这个消息队列运行在主线程,这个消息队列关联的Looper也在主线程,当在loop方法中执行handleMessage方法时,说明handleMessage执行在主线程,故handleMessage可以进行ui操作。
给一张流程图,感受下:
2.先给出这个机制的一些必须了解的类的概念
Message:用于封装消息的简单数据结构。里面包含消息的ID、数据对象、处理消息的Handler引用和Runnable等。
Handler:消息的发送者和最终消息处理者。
MessageQueue:消息队列,提供消息的添加、删除、获取等操作来管理消息队列。
Looper:用于建立消息循环并管理消息队列(MessageQueue),不停的从消息队列中抽取消息,分发下去并执行。
先了解下Message:
很清晰的看到Message的成员变量 Handler target;说明创建的Message由这个Handler来处理,还有一个成员变量 Runnable callback;如果Message给这个callback设置了值,那么优先执行这个callback。
上图没把源码截全面,其实Message类还有一个成员变量 Message next;可以在上图obtain方法中看出端倪。由于java不谈指针的概念,所以Message内部维护了一个Message类型的引用。所以Message类是链式存储的,从上图Message sPool也可以看出。我们可以从sPool中取出(获得)一个Message对象。
其实可以理解为MessageQueue中只有一个Message对象,因为Message链式存储,一个Message对象也能找到链条的下一个Message。
MessageQueue主要实现Message对象进出以及销毁队列的功能,不再详述。
Looper这个类有必要讲一下:主要功能是分发Message:贴源码:
着重看下Looper类的loop方法,在loop方法中一直遍历MessageQueue中的消息,然后通过取到的消息中的target,也就是创建该消息的Handler,通过target的处理消息方法处理该消息,那么我们看这个处理消息函数的源码。
最后来看看handler是如何构造出来,如何发送消息到消息队列,再如何从消息队列取出消息处理的。
先看构造handler类的构造函数吧
handler必须有looper类的引用,有了looper类的引用,自然与looper类关联的MessageQueue有引用关系。
聊聊handler如何发送消息,仔细查看源码,发现发送消息都由如下函数执行:
该方法就是调用MessageQueue的enqueueMessage(…)方法将指定的Message插入到消息队列中去,即加入Message链,并指明何时应该从消息队列中取出来执行。其中uptimeMillis就是绝对时间戳,uptimeMillis = current time + delayMillis。
postXXX系列函数来说,需要指定一个Runnable对象,在合适的时间执行。
实际上,他们最终调用的还是sendMessageAtTime函数,只不过中间多了一步,即根据Runnable创建Message对象。只不过该消息中包含了一个Runnable对象。消息的处理是在loop方法中运行的,不再详述。
总结:
在主线程创建的handler,当子线程完成某个具体的任务或者逻辑,在子线程中发送消息给消息队列,当处理该消息时,是在主线程中进行ui操作。这就完成了主线程和子线程的通信。这是handler机制的最正宗的用途。
当然每个线程都可以拥有一个完整的handler机制,开发者可以根据具体需求去使用,修改这个机制,但是终究是为了完成线程间通信的目的不会变。