- 一、Handler 构造函数
- 二、Handler 消息分发
- 三、MessageQueue 消息队列相关函数
一般使用 Handler 时 , 调用 Handler 的普通 无参构造函数 ,
public class Handler {
/**
* 默认的构造函数 , 与当前线程相关联.
* 如果该线程没有 Looper , 该 Handler 不能接受 Message 消息 , 并抛出异常
*/
public Handler() {
this(null, false);
}
}
上面的无参构造函数调用了下面的构造方法 ,
第一个参数 Callback callback 是一个回调 , mCallback = callback , 该回调直接设置给了 mCallback 成员变量 ,
在该方法中 , 调用 mLooper = Looper.myLooper() 获取线程本地变量 Looper ;
获取 Looper 中的消息队列 MessageQueue , mQueue = mLooper.mQueue ;
主线程的 Looper 是在 ActivityThread 中的 main 函数 中 , 使用 Looper.prepareMainLooper() 创建的 ,
在 ActivityThread 的 main 函数最后调用了 Looper.loop() , 无限循环获取主线程 Looper 中封装的 MessageQueue 消息队列中的消息 ;
参考 : 【Android 异步操作】Handler ( 主线程中的 Handler 与 Looper | Handler 原理简介 ) ,
public class Handler {
/**
* Use the {@link Looper} for the current thread with the specified callback interface
* and set whether the handler should be asynchronous.
*
* Handlers are synchronous by default unless this constructor is used to make
* one that is strictly asynchronous.
*
* Asynchronous messages represent interrupts or events that do not require global ordering
* with respect to synchronous messages. Asynchronous messages are not subject to
* the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.
*
* @param callback The callback interface in which to handle messages, or null.
* @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for
* each {@link Message} that is sent to it or {@link Runnable} that is posted to it.
*
* @hide
*/
public Handler(@Nullable Callback callback, boolean async) {
if (FIND_POTENTIAL_LEAKS) {
final Class klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread " + Thread.currentThread()
+ " that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
}
Handler 中的 Callack 回调 接口 ;
public class Handler {
/**
* Callback interface you can use when instantiating a Handler to avoid
* having to implement your own subclass of Handler.
*/
public interface Callback {
/**
* @param msg A {@link android.os.Message Message} object
* @return True if no further handling is desired
*/
boolean handleMessage(@NonNull Message msg);
}
}
二、Handler 消息分发
Handler 中的消息分发 , 在 Looper 的 loop 方法中 , 调用该消息 dispatchMessage 分发消息的方法 ,
在该分发消息方法中 , 首先会查看 消息 Message 中 是否有 Callback 回调 ,
如果有执行该回调 , 就是构造函数中赋值的 mCallback ,
如果没有就调用 Handler 中的 handleMessage 方法 ;
public class Handler {
/**
* 在这里处理 Message 消息.
*/
public void dispatchMessage(@NonNull Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
}
使用 Handler 发送消息时 , 会 调用各种发送消息的方法 , 如
- public final boolean sendMessage(@NonNull Message msg)
- public final boolean sendEmptyMessage(int what)
- public final boolean sendEmptyMessageDelayed
- public final boolean sendEmptyMessageAtTime
- public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis)
等方法 , 所有的发送消息的方法 , 最终都会调用 public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) 方法 ,
在该方法中 , 调用 MessageQueue queue = mQueue , 获取 消息队列 MessageQueue ,
然后调用 enqueueMessage(queue, msg, uptimeMillis) 方法 , 将消息加入到 消息队列 MessageQueue 中 ;
public class Handler {
/**
* Enqueue a message into the message queue after all pending messages
* before the absolute time (in milliseconds) uptimeMillis.
* The time-base is {@link android.os.SystemClock#uptimeMillis}.
* Time spent in deep sleep will add an additional delay to execution.
* You will receive it in {@link #handleMessage}, in the thread attached
* to this handler.
*
* @param uptimeMillis The absolute time at which the message should be
* delivered, using the
* {@link android.os.SystemClock#uptimeMillis} time-base.
*
* @return Returns true if the message was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting. Note that a
* result of true does not mean the message will be processed -- if
* the looper is quit before the delivery time of the message
* occurs then the message will be dropped.
*/
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);
}
}
三、MessageQueue 消息队列相关函数
下面的代码是将消息存储到消息队列中的 enqueueMessage 方法 ;
public final class MessageQueue {
boolean enqueueMessage(Message msg, long when) {
if (msg.target == null) {
throw new IllegalArgumentException("Message must have a target.");
}
if (msg.isInUse()) {
throw new IllegalStateException(msg + " This message is already in use.");
}
synchronized (this) {
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
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?