美文网首页Android开发
再读Handler源码,深入理解Handler运行逻辑

再读Handler源码,深入理解Handler运行逻辑

作者: 捉影T_T900 | 来源:发表于2018-07-24 00:04 被阅读5次

1、Handler
(1)构造函数


handler.png

传递参数说明:
Callback:如果Callback不为空,在 dispatchMessage(Message msg) 内执行回调
Looper:指定当前Handler所持有的Looper引用,从Looper中获取MessageQueue,获取到的mQueue将会执行removeCallback、removeMessages等将消息移除的操作。一个Handler有且只有一个Looper引用。
boolean:进行 enqueueMessage 消息入列的时候,指定Message消息是否异步,如果设置为true,则说明Message是异步的。

botain.png

方法说明:这个方法是用来生成Message的,Message的结构是一个链表,为什么要用链表?因为要进行高效的出列和入列,链表的优点是入列和出列只需要移动指针即可,效率更高。
参数是用来指定Message的 what、arg1、arg2、obj 的值的。

post.png

方法说明:这类方法是用来向MessageQueue队列加入Message对象的,Runnable将会被赋值到Message的Runnable对象中。这类方法最终都会调用 sendMessageAtTime 进行入列操作。

send.png

方法说明:这类方法也是用来向MessageQueue队列加入Message对象的,参数为Message对象,最终都会调用 sendMessageAtTime 进行入列操作。

removeCallback.png removeMessage.png

方法说明:用来移除MessageQueue中的Message的,根据what、runnable等条件进行条件删除。如果传Object == null,则删除所有Message。

总结:Handler必须持有Looper对象,如果没指定,则回去主线程的looper对象,
一个Handler有且只有一个looper对象。

2、Looper
(1)构造函数


Looper.png

生成MessageQueue和获得当前线程。

(2)prepare方法


prepare.png

一个线程只能有一个Looper,ThreadLocal是一种线程安全机制,用于存储Looper对象。

(3)prepareMainLooper方法


prepareMainLooper.png

ActivityThread在运行main方法时,会调用Looper.prepareMainLooper(),启动主线程的MainLooper。

(4)isCurrentThread方法


isCurrentThread.png

这个方法可以用来判断当前的线程是否和Looper所在的线程一致。

(5)loop方法


loop.png

死循环,不断迭代MessageQueue中的Message。必须保证Looper不为空才允许执行循环。
Message中持有Handler的引用(msg.target),msg.target.dispatchMessage(msg)调用Handler的dispatchMessage方法,执行 handleCallback 或者 handleMessage 处理消息响应的处理流程。
最后调用recycleUnchecked方法重置这个Message,并将重置后的Message对象指向链表的下一个引用,达到重复利用Message对象的效果,提高程序效率。

3、Message
(1)obtain方法


obtain.png

用于返回Message对象,特别注意obtain()方法,这里有一个缓冲池的概念


pool.png

缓冲池的大小sPoolSize = 50,以链表的形式保存Message缓冲池的数据,recycleUnchecked 回收Message对象时,会向缓冲池增加一个Message,当新建一个Message时,会优先从缓冲池内获取Message对象。类似ListView中view视图的复用,提高效率。

(2)target
target持有的是Handler的引用,target会在Looper中进行dispatchMessage的操作。

(3)Message是一个Parcelable对象,可以进行跨进程的通信,内部的数据存储变量是 what、arg1、arg2、obj。

4、MessageQueue
(1)这个是用来操作Message的,它并不是真正的队列,更像是一个辅助类。一个线程值拥有一个MessageQueue。

(2)next方法
在Looper中进行调用,用于获取Message对象。

(3)quit方法
退出Looper循环。主线程不能退出。

(4)enqueueMessage方法
消息入列。

(5)remove方法


remove.png

移除消息方法,调用方在Handler,内部依然会调用Message的回收方法 recycleUnchecked() 达到有效利用Message对象。

总结

好了,终于看完了,我想,下次应该可以吹的比较靠谱了吧。

相关文章

网友评论

    本文标题:再读Handler源码,深入理解Handler运行逻辑

    本文链接:https://www.haomeiwen.com/subject/inesmftx.html