手写 Handler、Message、Looper

50 阅读1分钟

实现简易 HandlerMessageLooper

class Handler {

    private var mLooper:Looper ?= null
    private var mQueue:MessageQueue ?= null

    init {
        Looper.prepare()
        mLooper = Looper.myLooper()
        mQueue = mLooper?.mQueue
    }
    fun postDelayed(r:Runnable, delayMillis:Long):Boolean {
        return sendMessageDelayed(Message(`when` = delayMillis, target = this, callback = r), delayMillis = delayMillis)
    }

    fun sendMessage(msg:Message):Boolean {
        return sendMessageAtTime(msg, System.currentTimeMillis())
    }

    fun sendMessageDelayed(msg:Message, delayMillis:Long):Boolean {
        return sendMessageAtTime(msg, System.currentTimeMillis() + if (delayMillis < 0) 0 else delayMillis)
    }

    private fun sendMessageAtTime(msg:Message, uptimeMillis:Long):Boolean {
        val queue = mQueue ?: return false
        return enqueueMessage(queue, msg, uptimeMillis);
    }

    private fun enqueueMessage(queue:MessageQueue, msg:Message, uptimeMillis:Long):Boolean {
        msg.target = this
        return queue.enqueueMessage(msg, uptimeMillis)
    }

    fun printMsg(){
        mQueue?.printMsg()
    }
}

data class Message(var next:Message?=null, var `when`:Long = 0, var obj:Any?=null, var what:Int = 0, var arg1:Int = 0, var target:Handler?= null, var callback:Runnable?= null)

class Looper private constructor(val quitAllowed:Boolean) {
    var mQueue:MessageQueue?= null

    companion object {
        private val sThreadLocal:ThreadLocal<Looper> = ThreadLocal()

        fun prepare() {
            prepare(true)
        }

        private fun prepare(quitAllowed:Boolean) {
            if (sThreadLocal.get() != null) {
                throw RuntimeException("Only one Looper may be created per thread");
            }
            sThreadLocal.set(Looper(quitAllowed));
        }

        fun myLooper():Looper? {
            return sThreadLocal.get();
        }
    }

    init {
        mQueue = MessageQueue()
    }
}

class MessageQueue {

    private var mMessages:Message?= null

    fun enqueueMessage(msg:Message, `when`:Long):Boolean {
        synchronized (this) {
            msg.`when` = `when`;
            var p = mMessages
            if (p == null || `when` == 0L || `when` < p.`when`) {
                // New head, wake up the event queue if blocked.
                msg.next = p;
                mMessages = msg;
            } else {
                // Inserted within the middle of the queue.  Usually we don't have to wake
                // up the event queue unless there is a barrier at the head of the queue
                // and the message is the earliest asynchronous message in the queue.
                var prev:Message?
                while (true) {
                    prev = p
                    p = p?.next
                    if (p == null || `when` < p.`when`) {
                        break
                    }
                }
                msg.next = p // invariant: p == prev.next
                prev?.next = msg
            }
        }
        return true
    }

    fun printMsg() {
        println("===================================printMsg================================")
        var head = mMessages
        while (head!= null) {
            println(head.obj)
            head = head.next
        }
    }
}

使用方法

打印队列内容

println("============================= imitate_handler ===================================")
val mHandler = Handler()
mHandler.sendMessage(Message(obj = "Message1"))
mHandler.sendMessage(Message(obj = "Message2"))
mHandler.sendMessage(Message(obj = "Message3"))
mHandler.printMsg()

输出结果

============================= imitate_handler ===================================
===================================printMsg================================
Message1
Message2
Message3

打印队列内容,模拟加入延时后的输出

println("============================= imitate_handler ===================================")
val mHandler = Handler()
mHandler.sendMessageDelayed(Message(obj = "Message1"), 10)
mHandler.sendMessageDelayed(Message(obj = "Message2"), 5)
mHandler.sendMessageDelayed(Message(obj = "Message3"), 0)
mHandler.printMsg()

输出结果

============================= imitate_handler ===================================
===================================printMsg================================
Message3
Message2
Message1