Handler消息机制

2018-09-25  本文已影响0人  南小夕

一、定义
Android SDK 提供给开发者方便进行异步消息处理的类

二、Handler的四大组件和运行机制

屏幕快照 2018-09-25 下午4.32.16.png

1、Handler四大组件:
(1)Message:是处理和接受消息的对象。
(2)Looper:线程持有,读取消息队列中消息,读到这个消息后交给handler来进行处理。
(3)MessageQueue:消息队列,以先进先出的方式来处理Handler发送来的消息。
(4)Handler:处理和发送消息。

2、Handler源码分析

首先看Handler的构造方法, 屏幕快照 2018-09-25 下午4.48.45.png
通过Looper.myLooper()方法创建一个Looper对象,如果为 null就会抛出“在一个没有调用Looper.prepare()方法的线程内部不能创建handler”异常。然后通过mLooper.mQueue获得MessageQueue对象,这个时候意味着handler和looper共用一个消息队列。
然后看一下消息发送源码, 屏幕快照 2018-09-25 下午5.01.10.png Handler 通过 send 发送消息 (sendMessage) ,当然 post 一系列方法最终也是通过 send 来实现的,在 send 方法中handler 会通过 enqueueMessage() 方法中的 enqueueMessage(msg,millis )向消息队列 MessageQueue 插入一条消息,同时会把本身的 handler 通过 msg.target = this 传入。
其实这个消息队列包括两种操作插入和读取,需要注意这个读取本身还伴随着删除操作。另外消息队列内部并不是用队列实现的,而是用单链表实现的。
先看一下插入操作queue.enqueueMessage()的代码实现, 屏幕快照 2018-09-25 下午5.04.38.png
还有一个方法读取next(), 屏幕快照 2018-09-25 下午5.46.26.png

再看一下looper如何管理MessageQueue。
首先看一下Looper中的prepare方法,他的内部其实是通过一个Thread Local容器来存取looper对象的,为什么要用ThreadLocal来存取呢?因为这样可以确保每一个线程获取到的looper都是唯一的,如果获取到的looper不为null就抛出异常,否则就创建一个looper对象存到threadLocal中。

屏幕快照 2018-09-25 下午7.02.44.png 看一下Looper的构造方法,在创建Looper对象的同时也将MessageQueue对象创建好,这样就能保证Looper持有来一个MessageQueue对象, 屏幕快照 2018-09-25 下午7.13.45.png
上一篇下一篇

猜你喜欢

热点阅读