美文网首页
小知识:Handler中post/send

小知识:Handler中post/send

作者: 一个追寻者的故事 | 来源:发表于2020-09-11 17:55 被阅读0次

    本篇内容很简单,纯属记录方便日后记忆。

    Handler消息机制细节就不多说了。我们知道,Looper不停的从消息队列中取出Message,然后分发给对应的Handler去处理。Handler附属于哪个线程取决于Handler构造时对应的 Looper附属的线程,即Handler构造的时候就确定了,它终究要为哪个线程的消息分发后的处理进行服务,也就决定了执行 Handler#dispatchMessage所在的线程。

    消息分发

    Message和Handler关联的方式很简单,用哪个Handler发送的消息,就用哪个Handler进行任务处理。最终会调用 Handler#dispatchMessage 进行消息处理:

    public class Handler{
        public void dispatchMessage(@NonNull Message msg) {
            if (msg.callback != null) {
                handleCallback(msg);
            } else {
                if (mCallback != null) {
                    if (mCallback.handleMessage(msg)) {
                        return;
                    }
                }
                handleMessage(msg);
            }
        }
    }
    

    我们看到无论如何会有一个 Message 对象分发过来,Message对象可以选择性的携带一些数据。

    dispatchMessage 进行分发的时候分了3种情况:
    1、如果 msg对象 中有 callback 属性,直接调用 callback#run 方法 「callback是一个实现了Runnable接口的实例」
    2、Handler 对象中有 mCallback属性,直接调用 mCallback#handleMessage,如果mCallback#handleMessage返回为true,分发结束;
    3、如果mCallback#handleMessage返回false,则继续执行 Handler#handleMessage进行消息分发。

    这里说明一下mCallback,不是Runnable类型,而是实现了如下类型「Callback」的实例,区别是有入参和返回值。

    public interface Callback {
        boolean handleMessage(@NonNull Message msg);
    }
    
    Message发送

    针对这种情况,在发送Message的时候演化了很多种形式:【这里简单列几种】
    首先定义Handler:

        class MyHandler : Handler {
            constructor() : super()
            constructor(callback: Callback) : super(callback)
            override fun handleMessage(msg: Message) {
                Log.e(MainActivity::class.java.name, "Handler - handleMessage: ${msg.what}")
            }
        }
    
    一、 Handler#postXXX(@NonNull Runnable r)
        private val handler0 = MyHandler()
    
        handler0.post {  // kotlin : lambda表达式
           Log.e(MainActivity::class.java.name, "Runnable - run")    
        }
    

    最终消息分发回走上边的第一种情况,直接结果:

        MainActivity: Runnable - run
    
    二、 Handler#sendXXX(XXX)
        private val handler1 = MyHandler(Handler.Callback {msg ->
            Log.e(MainActivity::class.java.name, "Callback - handleMessage: ${msg.what}")
            true  //这里
        })
    
        handler1.sendEmptyMessage(11)
    

    最终消息分发回走上边的第二种情况,直接结果:

        MainActivity: Callback - handleMessage: 11
    
        private val handler2 = MyHandler(Handler.Callback {msg ->
            Log.e(MainActivity::class.java.name, "Callback - handleMessage: ${msg.what}")
            false  //这里
        })
    
        handler2.sendEmptyMessage(11)
    

    最终消息分发回走上边的第三种情况,直接结果:

        MainActivity: Callback - handleMessage: 11
        MainActivity: Handler - handleMessage: 11
    

    总结:总体来说 post 的参数是Runnable,send的参数有一部分是 Message。不论哪种情况都会最终构建一个Message对象,然后发送到对应线程的消息队列中。

    还记得 Activity#runOnUiThread 方法的实现,也是使用了post的方法:

        public final void runOnUiThread(Runnable action) {
            if (Thread.currentThread() != mUiThread) {
                mHandler.post(action);
            } else {
                action.run();
            }
        }
    

    相关文章

      网友评论

          本文标题:小知识:Handler中post/send

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