本文基于 SDK-33
无参构造方法(已弃用)
@Deprecated
public Handler() {
this(null, false);
}
Callback 作为参数(已弃用)
public Handler(@Nullable Callback callback) {
this(callback, false);
}
Looper 作为参数
public Handler(@NonNull Looper looper) {
this(looper, null, false);
}
Looper、Callback 作为参数
public Handler(@NonNull Looper looper, @Nullable Callback callback) {
this(looper, callback, false);
}
异步消息标志作为参数(不对外公开)
public Handler(boolean async) {
this(null, async);
}
Callback 、异步消息标志作为参数(不对外公开)
public Handler(@Nullable Callback callback, boolean async) {
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Handler> 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;
}
Looper、Callback、异步消息标志作为参数(不对外公开)
public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
创建不进行自定义消息处理的异步处理 Handler
public static Handler createAsync(@NonNull Looper looper) {
if (looper == null) throw new NullPointerException("looper must not be null");
return new Handler(looper, null, true);
}
创建可以处理自定义消息的异步处理 Handler
public static Handler createAsync(@NonNull Looper looper, @NonNull Callback callback) {
if (looper == null) throw new NullPointerException("looper must not be null");
if (callback == null) throw new NullPointerException("callback must not be null");
return new Handler(looper, callback, true);
}
方法好几个,但其实可以这样划分:
关于同步障碍,MessageQueue 中会讲到
但是不管是哪种方式创建,都会走到 6 或 7,但不管是哪一种创建方式,都执行了这些初始化操作:
发送普通消息:
public final boolean sendMessage(@NonNull Message msg) {
return sendMessageDelayed(msg, 0);
}
发送普通延时消息
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 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);
}
这些方法最终都会调用到 enqueueMessage
方法:
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);
}
可以看到该方法执行了这些操作:
target
设置为此 HandlermAsynchronous
的值)enqueueMessage
方法将消息传入队列中MessageQueue 后面会写。
发送一个 Runnable 对象
public final boolean post(@NonNull Runnable r) {
return sendMessageDelayed(getPostMessage(r), 0);
}
发送一个定时的 Runnable 对象(不带 Token)
public final boolean postAtTime(@NonNull Runnable r, long uptimeMillis) {
return sendMessageAtTime(getPostMessage(r), uptimeMillis);
}
发送一个定时的 Runnable 对象(带 Token)
public final boolean postAtTime(
@NonNull Runnable r, @Nullable Object token, long uptimeMillis) {
return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);
}
发送一个延时执行的 Runnable 对象
public final boolean postDelayed(@NonNull Runnable r, long delayMillis) {
return sendMessageDelayed(getPostMessage(r), delayMillis);
}
发送一个延时带 what 标记的 Runnable 对象(不对外公开)
public final boolean postDelayed(Runnable r, int what, long delayMillis) {
return sendMessageDelayed(getPostMessage(r).setWhat(what), delayMillis);
}
发送一个延时带 Token 的 Runnable 对象
public final boolean postDelayed(
@NonNull Runnable r, @Nullable Object token, long delayMillis) {
return sendMessageDelayed(getPostMessage(r, token), delayMillis);
}
发送一个插队的 Runnable 对象
public final boolean postAtFrontOfQueue(@NonNull Runnable r) {
return sendMessageAtFrontOfQueue(getPostMessage(r));
}
postXXX 方法要点在于对 getPostMessage
方法的调用:
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
@UnsupportedAppUsage
private static Message getPostMessage(Runnable r, Object token) {
Message m = Message.obtain();
m.obj = token;
m.callback = r;
return m;
}
所以 postXXX 本质上还是通过 sendXXX 来发送消息的,只不过是为将 Message 的 callback 设置为我们的 Runnable 对象,通过 sendXXX 发送的消息不会设置 Callback。
调用 Handler 对象的移除消息方法,最终调用的是 MessageQueue 中对应的 removeMessage 方法:
public final void removeCallbacks(@NonNull Runnable r) {
mQueue.removeMessages(this, r, null);
}
public final void removeCallbacks(@NonNull Runnable r, @Nullable Object token) {
mQueue.removeMessages(this, r, token);
}
public final void removeMessages(int what) {
mQueue.removeMessages(this, what, null);
}
public final void removeMessages(int what, @Nullable Object object) {
mQueue.removeMessages(this, what, object);
}
public final void removeCallbacksAndMessages(@Nullable Object token) {
mQueue.removeCallbacksAndMessages(this, token);
}
具体移除过程,会在 MessageQueue 文章中讲解。
这个方法看注释就好了:
public void dispatchMessage(@NonNull Message msg) {
if (msg.callback != null) {
handleCallback(msg);//如果 Message 设置了 Runnable,则直接执行
} else {
if (mCallback != null) {//如果 Handler 设置了 Callback,则消息优先交给 Callback 处理
if (mCallback.handleMessage(msg)) {//如果 Callback 处理了 Message,则直接返回,不再经过 handleMessage 方法
return;
}
}
handleMessage(msg);//handleMessage 方法处理 Message
}
}
上面就是最常用的 Handler 功能,Handler 还有一些其他功能:
public final Message obtainMessage(){
return Message.obtain(this);
}
public final Message obtainMessage(int what){
return Message.obtain(this, what);
}
public final Message obtainMessage(int what, @Nullable Object obj) {
return Message.obtain(this, what, obj);
}
public final Message obtainMessage(int what, @Nullable Object obj) {
return Message.obtain(this, what, obj);
}
public final Message obtainMessage(int what, int arg1, int arg2){
return Message.obtain(this, what, arg1, arg2);
}
public final Message obtainMessage(int what, int arg1, int arg2, @Nullable Object obj) {
return Message.obtain(this, what, arg1, arg2, obj);
}
可以看到,Handler 创建 Message 实际上还是调用了 Message 创建对象的方法,只不过是把自身作为参数传入了 Message 的 obtain
方法,为 Message 设置了 target
,关于 Message 后面会有专门文章分析。
//检查队列中是否有未处理的对应 what 的 Message
public final boolean hasMessages(int what) {
return mQueue.hasMessages(this, what, null);
}
//检查队列中是否有未处理的、对应 what、obj == object 的 Message
public final boolean hasMessages(int what, @Nullable Object object) {
return mQueue.hasMessages(this, what, object);
}
//检查消息队列中是否有未处理的、带有 Callback 的 Message
public final boolean hasCallbacks(@NonNull Runnable r) {
return mQueue.hasMessages(this, r, null);
}
获取和当前 Handler 绑定的 Looper:
public final Looper getLooper() {
return mLooper;
}