「这是我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战」
Handler机制原理
Handler
本章节主要介绍handler的消息发送的流程。
public final boolean sendMessage(@NonNull Message msg) {
return sendMessageDelayed(msg, 0);
}
public final boolean sendEmptyMessage(int what)
{
return sendEmptyMessageDelayed(what, 0);
}
public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
Message msg = Message.obtain();
msg.what = what;
return sendMessageDelayed(msg, delayMillis);
}
public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
Message msg = Message.obtain();
msg.what = what;
return sendMessageAtTime(msg, uptimeMillis);
}
public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
public final boolean sendMessageAtFrontOfQueue(@NonNull Message msg) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, 0);
}
public final boolean executeOrSendMessage(@NonNull Message msg) {
if (mLooper == Looper.myLooper()) {
dispatchMessage(msg);
return true;
}
return sendMessage(msg);
}
private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
long uptimeMillis) {
msg.target = this;
msg.workSourceUid = ThreadLocalWorkSource.getUid();
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
从上面这几个方法看,最终都会执行enqueueMessage方法。
在发送消息时给 Message 设置了 target = this 也就是当前的 Handler 对象。
在这个方法中最后会调用MessageQueue的enqueueMessage(msg,uptimeMillis)方法。说明handler发送一条消息其实就是在消息队列插入一条消息。在Looper的loop方法中,从Message Queue中取出消息调msg.target.dispatchMessage(msg);这里其实就是调用了Handler的dispatchMessage(Message msg)方法。
接下来去看Handler是如何接收消息的。
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
public interface Callback {
public boolean handleMessage(Message msg);
}
public void handleMessage(Message msg) {
}
dispatchMessage() 方法还是通过handleMessage() 来回调的UI界面的方法。中间如果有msg.Runnable对象的话,就跑他的run方法。没有就执行hangleMessage()。这个空方法就是我们创建Handler时重写的方法,根据msg.what进行消息的处理。
Handler.Callback callback = new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message msg) {
Log.e("MainActivity", "callback handleMessage");
return false;
}
};
Handler handler = new Handler(callback){
@Override
public void handleMessage(@NonNull Message msg) {
Log.e("MainActivity", "Handler handleMessage");
}
};
Message msg = new Message();
msg.what=1;
handler.sendMessage(msg);
dispatchMessage中有一个callback,上面介绍了callback的使用,如过返回为true,不会执行Handler handleMessage方法,返回为false会执行。打印的log。