一、Handler定义:
Handler是什么:Handler机制允许你在一个线程的MessageQueue中发送和处理Message对象和Runnable对象。 每个Handler实例都与一个单独的线程以及该线程的消息队列相关联。当你创建一个新的Handler 时它会被绑定到一个Looper上。Handler会将消息和Runnable对象传递给该Looper的消息队 列,并在Looper所在的线程上执行它们。
二、Handler相关知识点:
- Handler的几个关键要素:Handler、Message、MessageQueue、Looper
1、Handler:负责将Message或者Runnable发送到消息队列中,并且安排他们被处理
2、Message:消息对象。
暂时无法在YesV2.0文档外展示此内容
3、MessageQueue:消息队列,用来存消息。既然是队列,正常就遵循队尾插入,队头取出的原则
4、Looper:消息队列的管理器,负责不断从消息队列中取出消息并分发到相应的Handler中处理
-
Handler的消息类型: 同步消息、异步消息、同步屏障
- 同步消息:普通消息
- 异步消息:调用setAsynchronouse(true)设置异步消息
- 同步屏障:Message消息中的target字段为null,当在消息队列中插入了屏障消息后,在屏障消息之后的普通消息将不会执行,优先执行异步消息。注意异步消息要和同步屏障一起使用才有效果。
三、Handler流程分析:
Handler 流程 及源码分析:
//构造Handler的时候会取出looper的队列赋值过来
public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
//通过sendMessage方法发送消息,最终都是调用到此处
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);
}
private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
long uptimeMillis) {
//将Handler与target绑定
msg.target = this;
msg.workSourceUid = ThreadLocalWorkSource.getUid();
//设置为异步消息
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
boolean enqueueMessage(Message msg, long when) {
//按理来说这块既然target为空会抛异常,那怎么会出现同步屏障呢?所以同步屏障肯定不是从这来的
if (msg.target == null) {
throw new IllegalArgumentException("Message must have a target.");
}
synchronized (this) {
if (msg.isInUse()) {
throw new IllegalStateException(msg + " This message is already in use.");
}
if (mQuitting) {
IllegalStateException e = new IllegalStateException(
msg.target + " sending message to a Handler on a dead thread");
Log.w(TAG, e.getMessage(), e);
msg.recycle();
return false;
}
msg.markInUse();
//消息执行时间
msg.when = when;
Message p = mMessages;
boolean needWake;
if (p == null || when == 0 || when < p.when) {
// New head, wake up the event queue if blocked.573
//重新设置链头,将这个消息放在链头
msg.next = p;
mMessages = msg;
needWake = mBlocked;
} 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
needWake = mBlocked && p.target == null && msg.isAsynchronous();
//根据设置的延时时间插入消息在队列
Message prev;
for (;;) {
prev = p;
p = p.next;
if (p == null || when < p.when) {
break;
}
if (needWake && p.isAsynchronous()) {
needWake = false;
}
}
msg.next = p; // invariant: p == prev.next
prev.next = msg;
}
// We can assume mPtr != 0 because mQuitting is false
if (needWake) {
nativeWake(mPtr);
}
}
return true;
}
//一个线程只能由一个Looper
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
public static void loop() {
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
if (me.mInLoop) {
Slog.w(TAG, "Loop again would have the queued messages be executed" + " before this one completed.");
}
me.mInLoop = true;
...
...
for (;;) {
//死循环执行loopOnce
if (!loopOnce(me, ident, thresholdOverride)) {
return;
}
}
}
private static boolean loopOnce(final Looper me,final long ident,
final int thresholdOverride){
//
Message msg = me.mQueue.next(); // might block
...
...
try {
//调用dispatchMessage分发Message target就是我们绑定的Handler
msg.target.dispatchMessage(msg);
...
}
...
...
return true;
}
public void dispatchMessage(@NonNull Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
//Handler 实现线程切换,其实依赖的是 Looper,因为在 Handler 初始化的时候就跟 Looper绑
//定了,而Looper 又是跟线程绑定的,所以,Handler 最后执行 HandleMessage() 方法的时候
//的线程就是 Looper 所在的线程。
//当上面条件均不成立,就会走到此处,就是我们平时重写的handleMessage,一般我们传入的就是getMainLooper,所以就切回到主线程了
handleMessage(msg);
}
}
四、总结:
Handler 背后还有 Looper、MessageQueue、Message
- message:消息。
- MessageQueue:消息队列,负责消息的存储与管理,负责管理由 Handler 发送过来的 Message。读取会自动删除消息,单链表维护,插入和删除上有优势。在其next()方法中会无限循环,不断判断是否有消息,有就返回这条消息并移除。
- Looper:消息循环器,负责关联线程以及消息的分发,在该线程下从 MessageQueue获取 Message,分发给Handler,Looper创建的时候会创建一个 MessageQueue,调用loop()方法的时候消息循环开始,其中会不断调用messageQueue的next()方法,当有消息就处理,否则阻塞在messageQueue的next()方法中。当Looper的quit()被调用的时候会调用messageQueue的quit(),此时next()会返回null,然后loop()方法也就跟着退出。
- Handler:消息处理器,负责发送并处理消息,面向开发者,提供 API,并隐藏背后实现的细节。
使用 Handler 前,要先创建 Looper 或者使用主线程的 Looper
主线程的 Looper 不允许退出
Runnable 被封装进了 Message,可以说是一个特殊的 Message