手写Handler
2020-05-20 本文已影响0人
yqianqiao
前言
上篇文章已经分析了handler,详见handlert源码分析
下面我们来手写handler,先看大纲图
- Handler
open class Handler {
private var mLooper= Looper.myLooper()
private val mQueue = mLooper.mQueue
//重写方法
open fun handlerMessage(msg: Message) {
}
//发送消息
fun sendMessage(msg: Message) {
msg.target = this
//消息入列
mQueue.enqueueMessage(msg)
}
//消息分发
fun dispatchMessage(msg: Message){
handlerMessage(msg)
}
}
初始化的时候通过Looper.myLooper()
获取到Looper
对象以及MessageQueue
,发送消息的时候将this
传入消息中,一起放入消息队列MessageQueue
中。消息分发回调重写方法handlerMessage
。
- Looper
//私有构造方法,只能通过prepare()调用
class Looper private constructor() {
//初始化MessageQueue
var mQueue = MessageQueue()
companion object {
//线程变量 Map<Thread,Looper>
private val sThreadLocal = ThreadLocal<Looper>()
//设置当前线程looper对象
fun prepare() {
if (sThreadLocal.get() != null) {
throw RuntimeException("Only one Looper may be created per thread")
}
sThreadLocal.set(Looper())
}
//获取当前线程Looper对象
fun myLooper(): Looper = sThreadLocal.get()
fun loop() {
//获取当前线程Looper
val me = myLooper()
//开启循环取消息
while (true) {
//在消息队列中取消息
val msg = me.mQueue.next()
//通过消息绑定的handler来回调dispatchMessage方法
msg.target?.dispatchMessage(msg)
}
}
}
}
- MessageQueue
class MessageQueue {
//消息阻塞队列
private val blockingQueue = ArrayBlockingQueue<Message>(50)
fun enqueueMessage(msg: Message) {
//消息入列
blockingQueue.put(msg)
}
fun next(): Message {
//取消息 当取不到消息时阻塞在这这里
return blockingQueue.take()
}
}
- Message
class Message {
//标记
var arg1 = 0
//发送的类
var any: Any? = null
//handler
var target: Handler? = null
}
- ActivityThread
class ActivityThread {
companion object {
@JvmStatic
fun main(args: Array<String>) {
//初始化ThreadLocal值。初始化Looper,MessageQueue
Looper.prepare()
//创建handler并重写handlerMessage接收消息
val handler = object : Handler() {
override fun handlerMessage(msg: Message) {
System.out.println("接收消息所在线程: ${Thread.currentThread().name}")
System.out.println("接收内容 : arg1 : ${msg.arg1} any = ${msg.any}")
}
}
//创建一个子线程
Thread {
System.out.println("发送消息所在线程 : ${Thread.currentThread().name}")
//在子线程中发送消息
val message = Message()
message.arg1 = 12
message.any = "测试内容"
handler.sendMessage(message)
}.start()
//启动消息循环
Looper.loop()
}
}
}
运行结果