Handler基本使用


Handler的基本使用

kotlin代码

val mHandler = Handler(Looper.getMainLooper()) { msg ->
    println(msg.what)
    true
}

然后在工作线程中将相关信息通过sendMessage( )发送给handler
让handler在主线程中进行UI的相关更新操作

Thread(Runnable {
    var i =1
    while (i<200){
        val message = Message()
        message.what = i++
        mHandler.sendMessage(message)
    }
}).start()

其实handler实现对收到的message进行处理还有一种方式,重写handler的handleMessage方法

class  HandlerClass :Handler(Looper.getMainLooper()){
     override fun handleMessage(msg: Message) {
         super.handleMessage(msg)
         println("handleMessage"+msg.what.toString())
     }
 }

源码解析

那么这跟上面那种实现Handler.Callback 的形式有什么不同呢,为了方便观察,我们把第一种写的更清晰一点

val mHandler = Handler(Looper.getMainLooper(),object :Handler.Callback{
    override fun handleMessage(msg: Message): Boolean {
        println("Callback"+msg.what.toString())
        return true
    }
}) 

两个不同点:
一个是重写了Handler类中的handleMessage方法一个是重写了Handler.Callbac接口的handleMessage方法 。
实现接口的方式有一个布尔类型的返回值,那么这个返回值的作用是什么呢 我们可以看看源码

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

mCallback.handleMessage(msg) 告诉我们 再分发message的时候如果返回值为true便只执行接口中重写的handleMessage方法而不去执行Handler类中的handleMessage方法只有当返回值为false的时候才会先后执行这两个方法。
那么又有一个问题引发了我们的思考,在第二三行中比他们优先级更高的方法是什么呢。其实这涉及到了handler的另一种使用方式Handler.post( ) 先上代码

val mHandler = Handler(Looper.getMainLooper())//先得到handler的一个实例
//然后在子线程中进行一个ui更新的post
       Thread{
            mHandler.post(Runnable { 
                mText.text = "mHandler.post"
            })
        }.start()

我们这里通过post方法传进了一个Runnable的实例,它会在后面被赋值给内部新获取的一个message实例的callback成员变量

private static Message getPostMessage(Runnable r) {
    Message m = Message.obtain();
    m.callback = r;
    return m;
}

而这个成员变量就是我们上面分发信息中的 msg.callback,这样一下子就豁然开朗了。
其实像我们可能是用的很多的view.post其实也是调用了handler.post方法

public boolean post(Runnable action) {
    final AttachInfo attachInfo = mAttachInfo;
    if (attachInfo != null) {
        return attachInfo.mHandler.post(action);
    }

    // Postpone the runnable until we know on which thread it needs to run.
    // Assume that the runnable will be successfully placed after attach.
    getRunQueue().post(action);
    return true;
}

所以说还是得多看看源码啊。


文章作者: Lao Wu
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Lao Wu !
评论
  目录