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;
}
所以说还是得多看看源码啊。