Android-Handler源码解析-Handler(一)
源码版本:
* Handler:SDK-35
* 更新时间:2025-3月导航:
成员变量
// 是否发现(检查)潜在的泄漏
private static final boolean FIND_POTENTIAL_LEAKS = false;
// Log的Tag
private static final String TAG = "Handler";
// 主线程Handler
private static Handler MAIN_THREAD_HANDLER = null;
// 此Handler的Looper
@UnsupportedAppUsage
final Looper mLooper;
// 此Handler的消息队列,来自Looper对象。
final MessageQueue mQueue;
// 此Handler分发消息时,在处理非Runnable消息时,优先处理Message的Callback,其次再handleMessage()处理。
@UnsupportedAppUsage
final Callback mCallback;
// 是否是异步Handler,即是否send或post的消息全部都是异步消息,默认为false。
final boolean mAsynchronous;
// 跨进程通信,消息发送者。
@UnsupportedAppUsage
IMessenger mMessenger;
// 如果是共享Handler,则不允许某些危险操作。
private final boolean mIsShared;
说明:
1.Looper相关介绍,请看Android-Handler源码解析-Looper。
2.MessageQueue相关介绍,请看Android-Handler源码解析-MessageQueue。
3.Handler为什么需要持有Looper、MessageQueue,因为Handler发送消息等操作需要知道发送到哪个MessageQueue,而MessageQueue需要从Looper中获取,以便发出的消息能进行轮询分发 。
创建Handler
想要使用Handler,首先要创建Handler,所以我们接下来看下它是如何被创建的。
new Handler()
默认Looper
Handler()
@Deprecated
public Handler() {
this(null, false);
}
Handler(Callback)
@Deprecated
public Handler(@Nullable Callback callback) {
this(callback, false);
}
Handler(boolean)
/** @hide */
public Handler(boolean async) {
this(null, async);
}
Handler(Callback, boolean)
/** @hide */
public Handler(@Nullable Callback callback, boolean async) {
if (FIND_POTENTIAL_LEAKS) {
// 检查潜在的泄漏,为false不检查。
final Class<? extends Handler> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
// 匿名类、成员类、局部类,并且不是静态的,警告提示(以下Handler类应该是静态的,否则可能会发生泄漏)。
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}
// 获取当前线程的Looper
mLooper = Looper.myLooper();
if (mLooper == null) {
// 当前线程没有Looper,则抛出异常提示(不能在没有调用Looper.prepare()的线程中创建handler)。
throw new RuntimeException(
"Can't create handler inside thread " + Thread.currentThread()
+ " that has not called Looper.prepare()");
}
// 获取Looper的消息队列
mQueue = mLooper.mQueue;
// 记录CallBack
mCallback = callback;
// 记录是否是异步的
mAsynchronous = async;
// 如果是共享Handler,则不允许某些危险操作。
mIsShared = false;
}
以上构造方法,使用默认的Looper(当前线程的Looper)。如果这个线程没有looper,则抛出异常。
说明:
1.Handler()、Handler(Callback)两个构造方法已经被标记为@Deprecated(过时),因为在Handler构造过程中选择一个默认的Looper可能会导致崩溃(在这个线程上没有调用Looper.prepare()),推荐使用指定Looper的构造方法。
2.Handler(boolean)、Handler(Callback, boolean)两个构造方法已经被标记为@hide(隐藏),只能系统内部使用。
3. 使用默认的Looper(当前线程的Looper),如果这个线程没有looper,则抛出异常。
4. 参数Callback,为此Handler分发消息时,优先处理非Runnable的Message的Callback,详细见后面-分发Message。
5. 参数async,为此Handler发送消息时,是否全部发送同步(默认同步)、异步消息,详细见后面-发送Message。
6. 消息,分为同步消息和异步消息,默认为同步消息,详细请看Android-Handler源码解析-Message-异步Message。
7. 同步屏障,会屏障同步消息,确保只有异步消息执行,详细请看Android-Handler源码解析-MessageQueue-同步屏障。
指定Looper
Handler(Looper)
public Handler(@NonNull Looper looper) {
this(looper, null, false);
}
Handler(Looper, Callback)
public Handler(@NonNull Looper looper, @Nullable Callback callback) {
this(looper, callback, false);
}
Handler(Looper, Callback, boolean)
/** @hide */
@UnsupportedAppUsage
public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async) {
this(looper, callback, async, /* shared= */ false);
}
Handler(Looper, Callback, boolean, boolean)
/** @hide */
public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async,
boolean shared) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
mIsShared = shared;
}
以上构造方法,使用指定的Looper而不是默认的Looper。
说明:
1.Handler(Looper)、Handler(Looper, Callback)两个构造方法未被标记为@Deprecated(过时),并使用指定的Looper,推荐使用。
2.Handler(Looper, Callback, boolean)、Handler(Looper, Callback, boolean, boolean)构造方法已经被标记为@hide(隐藏),只能系统内部使用。
Handler.createAsync()
Handler.createAsync(Looper)
@NonNull
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.createAsync(Looper, Callback)
@NonNull
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);
}
Handler.createAsync()方法,为静态方法,创建一个异步Handler,其发布的Message都是异步的,不受同步障碍(如显示vsync)的影响。
小结
- 创建–同步
Handler,分为未指定Looper、指定Looper两种方式创建。
- 未指定
Looper,则使用当前线程的Looper,不推荐使用。- 指定
Looper,推荐使用,构造方法为Handler(Looper)、Handler(Looper, Callback)。- 创建–异步
Handler,使用Handler.createAsync(Looper)、Handler.createAsync(Looper, Callback)方法创建,其发出的Message都是异步的。
创建Message
想要使用Message,可以通过Handler创建Message,所以我们接下来看下它是如何被创建的。
obtainMessage()
@NonNull
public final Message obtainMessage() {
return Message.obtain(this);
}
@NonNull
public final Message obtainMessage(int what) {
return Message.obtain(this, what);
}
@NonNull
public final Message obtainMessage(int what, @Nullable Object obj) {
return Message.obtain(this, what, obj);
}
@NonNull
public final Message obtainMessage(int what, int arg1, int arg2) {
return Message.obtain(this, what, arg1, arg2);
}
@NonNull
public final Message obtainMessage(int what, int arg1, int arg2, @Nullable Object obj) {
return Message.obtain(this, what, arg1, arg2, obj);
}
以上obtainMessage()方法 ,从全局消息池返回一个新的消息。内部使用Message.obtain()方法创建消息,并将其Message的target为当前Handler。
说明:
1.Message.obtain()相关介绍,请看Android-Handler源码解析-Message-创建Message。
小结
handler.obtainMessage()方法,使用Message.obtain()方法创建消息,并将其Message的target为当前Handler,以进行Message和Handler一对一关系绑定。
发送Message
Message创建好后,便可以发送消息了,Handler除了可以通过sendMessage()方法发送消息,还可以通过post()方法执行指定的Runnable任务,所以我们接下来看下它们是如何被发送的。
send-Message
sendMessage()
public final boolean sendMessage(@NonNull Message msg) {
return sendMessageDelayed(msg, 0);
}
sendEmptyMessage()
public final boolean sendEmptyMessage(int what) {
return sendEmptyMessageDelayed(what, 0);
}
sendMessageDelayed()
public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
sendEmptyMessageDelayed()
public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
Message msg = Message.obtain();
msg.what = what;
return sendMessageDelayed(msg, delayMillis);
}
sendMessageAtTime()
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);
}
sendEmptyMessageAtTime()
public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
Message msg = Message.obtain();
msg.what = what;
return sendMessageAtTime(msg, uptimeMillis);
}
sendMessageAtFrontOfQueue()
public final boolean sendMessageAtFrontOfQueue(@NonNull Message msg) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtFrontOfQueue() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, 0);
}
以上方法,为发送立即消息、发送延迟消息、发送指定时刻消息、将消息排在消息队列的前面。
说明:
1.sendMessage()、sendEmptyMessage()为发送立即Message,sendMessageDelayed()、sendEmptyMessageDelayed()为发送延迟Message,sendMessageAtTime()、sendEmptyMessageAtTime()为发送指定时刻Message,sendMessageAtFrontOfQueue()为发送排在消息队列的前面的Message。
2.sendMessageAtFrontOfQueue(),为将消息排在消息队列的前面,以便在消息loop的下一次迭代中处理。此方法仅用于非常特殊的情况——它很容易使消息队列挨饿、导致排序问题或产生其它意想不到的副作用。
3. 参数msg为要发送的Message,参数what为Message的标识,参数delayMillis为延迟的时间,参数uptimeMillis为指定的时间。
发送立即消息、发送延迟消息、指定时刻发送、将消息排在消息队列的前面,他们最终调用的都是enqueueMessage()方法,我们接下来看下enqueueMessage()方法。
enqueueMessage()
private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
long uptimeMillis) {
// 指定Message的Handler为此Handler
msg.target = this;
msg.workSourceUid = ThreadLocalWorkSource.getUid();
// 如果此Handler是异步的,则发送的所有消息都是异步的。
if (mAsynchronous) {
msg.setAsynchronous(true);
}
// 使用MessageQueue将消息加入到消息队列中
return queue.enqueueMessage(msg, uptimeMillis);
}
enqueueMessage()方法,为将Message加入到MessageQueue中。
说明:
1. 指定此Message的target为此Handler,使此Message和此Handler一对一关联,以便此Message由此Handler处理。
1. 由此Handler发出的所有Message都和此Handler绑定得知,多个Message可以共用一个Handler。
2. 如果此Handler是异步的,则发送的所有消息都是异步的。
3.uptimeMillis参数为消息执行时刻,立即执行的为SystemClock.uptimeMillis(),延时执行的为SystemClock.uptimeMillis() + delayMillis,指定时刻发送的为指定的,将消息排在消息队列的前面的为0。
4.MessageQueue入队消息相关介绍,请看Android-Handler源码解析-MessageQueue-入队Message。
post-Runnable
post()
public final boolean post(@NonNull Runnable r) {
return sendMessageDelayed(getPostMessage(r), 0);
}
postDelayed()
public final boolean postDelayed(@NonNull Runnable r, long delayMillis) {
return sendMessageDelayed(getPostMessage(r), delayMillis);
}
/** @hide */
public final boolean postDelayed(Runnable r, int what, long delayMillis) {
return sendMessageDelayed(getPostMessage(r).setWhat(what), delayMillis);
}
public final boolean postDelayed(@NonNull Runnable r, @Nullable Object token, long delayMillis) {
return sendMessageDelayed(getPostMessage(r, token), delayMillis);
}
postAtTime()
public final boolean postAtTime(@NonNull Runnable r, long uptimeMillis) {
return sendMessageAtTime(getPostMessage(r), uptimeMillis);
}
public final boolean postAtTime(@NonNull Runnable r, @Nullable Object token, long uptimeMillis) {
return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);
}
postAtFrontOfQueue()
public final boolean postAtFrontOfQueue(@NonNull Runnable r) {
return sendMessageAtFrontOfQueue(getPostMessage(r));
}
以上都是调用getPostMessage()方法将Runnable进行包装返回Message,接下来我们来看一下getPostMessage()方法的实现。
getPostMessage()
private static Message getPostMessage(Runnable r) {
// 使用复用获取新的Message
Message m = Message.obtain();
// 将Runnable保存到Message的callback中
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;
}
以上方法,为发送立即Runnable、发送延迟Runnable、发送指定时刻Runnable、将Runnable排在消息队列的前面。
通过getPostMessage()方法将Runnable包装为Message然后调用上面send-Message对应的发送消息的方法进行发送。
小结
- 发送消息分为
send-Message、post-Runnable,post-Runnable底层也是通过send-Message进行发送(将Runnable保存到Message的callback中)。sendMessageAtFrontOfQueue()、postAtFrontOfQueue(),方法为将消息排在消息队列的前面,会使原来有序的队列变为无序的,谨慎使用。- 通过
handler发送的消息,最终都会将此Message和此Handler一对一关联,以便此Message由此Handler处理。- 如果此
Handler是异步的,则发送的所有消息都是异步的。
分发Message
当Looper.loop()方法开启后,并且此Looper的MessageQueue的next()方法返回一个Message后,会调用Handler的dispatchMessage()方法,代码如下。
Loop->loopOnce()
private static boolean loopOnce(final Looper me,
final long ident, final int thresholdOverride) {
Message msg = me.mQueue.next(); // might block
...
// 调用Handler分发消息
msg.target.dispatchMessage(msg);
...
}
接下来我们来看一下Handler的dispatchMessage()方法。
dispatchMessage()
Handler->dispatchMessage()
public void dispatchMessage(@NonNull Message msg) {
if (msg.callback != null) {
// 处理Runnable
handleCallback(msg);
} else {
// 处理Message
if (mCallback != null) {
// handler的Callback不为空,优先它处理。
if (mCallback.handleMessage(msg)) {
// 返回true,表示handler的Callback已经处理,不再需要handler的handleMessage()方法处理。
return;
}
}
// 使用handler的handleMessage方法处理
handleMessage(msg);
}
}
dispatchMessage()方法,为分发消息,分为处理Runnable、处理Message。而处理Message优先handler的mCallback处理,如果mCallback为空或者其mCallback.handleMessage(msg)返回false,其次再handler的handleMessage()方法处理。
说明:
1.dispatchMessage()方法为public并且不是final,所以可以被覆写,一般不覆写此方法。
接下来我们先来看一下处理Callback的handleCallback()方法。
handleCallback()
private static void handleCallback(Message message) {
// 调用callback.run()方法(即runnable.run()方法)执行
message.callback.run();
}
handleCallback()方法,直接调用message的callback(即Runnable)的run()方法执行。
接下来我们再来看一下优先处理Message的Handler.Callback类,其次再来看一下其次处理的handleMessage()方法。
Handler.Callback类
public interface Callback {
/**
* @return 如果不需要进一步处理,则为True。
*/
boolean handleMessage(@NonNull Message msg);
}
如果handler.mCallback有设置值,则优先它来处理,并且mCallback.handleMessage(msg)方法返回true,则不再需要此handler的handleMessage()方法处理。
handleMessage()
public void handleMessage(@NonNull Message msg) {
}
handleMessage()方法,为处理消息,我们可以通过Message的what的值来区分,来实现自己的逻辑。
说明:
1.handleMessage()方法为public并且不是final,所以可以被覆写,一般覆写此方法。
小结
- 分发
Message,它是通过Handler的dispatchMessage()方法进行分发处理。- 分发
Message,它分为处理Runnable、处理Message。
2.1.处理Runnable,直接调用callback(即Runnable)的run()方法执行。
2.2.处理Message,优先handler的mCallback处理,其次再handler的handleMessage()方法处理。dispatchMessage()、handleMessage()方法均可以被覆写,一般只覆写handleMessage()方法即可。
移除Messages、Runnable
removeMessages()
public final void removeMessages(int what) {
mQueue.removeMessages(this, what, null);
}
public final void removeMessages(int what, @Nullable Object object) {
mQueue.removeMessages(this, what, disallowNullArgumentIfShared(object));
}
removeEqualMessages()
/** @hide */
public final void removeEqualMessages(int what, @Nullable Object object) {
mQueue.removeEqualMessages(this, what, disallowNullArgumentIfShared(object));
}
removeCallbacks()
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);
}
removeCallbacksAndMessages()
public final void removeCallbacksAndMessages(@Nullable Object token) {
mQueue.removeCallbacksAndMessages(this, disallowNullArgumentIfShared(token));
}
removeCallbacksAndEqualMessages()
/** @hide */
public final void removeCallbacksAndEqualMessages(@Nullable Object token) {
mQueue.removeCallbacksAndEqualMessages(this, disallowNullArgumentIfShared(token));
}
private Object disallowNullArgumentIfShared(@Nullable Object arg) {
if (mIsShared && arg == null) {
// 是共享Handler,则不允许参数为空。
throw new IllegalArgumentException("Null argument disallowed for shared handler."
+ " Consider creating your own Handler instance.");
}
return arg;
}
以上方法,为【移除】此Handler发出的Message(指定what、obj)、Runnable(指定runnable、token),全部都是通过调用MessageQueue的removeXXX方法进行移除。
内部调用了disallowNullArgumentIfShared()方法,为如果是共享Handler(mIsShared为true)则不允许参数为空,默认mIsShared为false。
说明:
1.removeMessages()、removeEqualMessages():为删除此Handler发出的Message,参数what为Message的标识,参数obj为辅助(删除同时满足what和obj的Message)。
2.removeCallbacks():为删除此Handler发出的Runnable,参数runnable为Runnable对象,参数token为辅助(删除同时满足runnable和token的Runnable)。
3.removeCallbacksAndMessages()、removeCallbacksAndEqualMessages():为删除此Handler发出的Message和此Runnable,参数token为Message、Runnable的标识。参数token为删除所有obj为token的Runnable和Message,如果token为空,所有Runnable和Message将被删除。
4.removeEqualMessages()、removeCallbacksAndEqualMessages():两个为@hide方法,只能系统调用。
5. 带有Equal和不带有Equal的区别是,在比较辅助参数obj、token时,不带有Equal是比较的==(对象引用),而带有Equal比较的是equals()方法(对象内容)。
6.MessageQueue移除消息相关介绍,请看Android-Handler源码解析-MessageQueue-移除Message。
小结
- 【移除】此Handler发出的
Message(指定what、obj)、Runnable(指定runnable、token),全部都是通过调用MessageQueue的removeXXX方法进行移除。removeCallbacksAndMessages():参数token如果为空,则删除此Handler发出的所有Runnable和Message。- 带有
Equal和不带有Equal的区别是,在比较辅助参数obj、token时,不带有Equal是比较的==(对象引用),而带有Equal比较的是equals()方法(对象内容)。
是否有Messages、Runnable
hasMessages()
public final boolean hasMessages(int what) {
return mQueue.hasMessages(this, what, null);
}
public final boolean hasMessages(int what, @Nullable Object object) {
return mQueue.hasMessages(this, what, object);
}
hasEqualMessages()
/** @hide */
public final boolean hasEqualMessages(int what, @Nullable Object object) {
return mQueue.hasEqualMessages(this, what, object);
}
hasCallbacks()
public final boolean hasCallbacks(@NonNull Runnable r) {
return mQueue.hasMessages(this, r, null);
}
hasMessagesOrCallbacks()
/** @hide */
public final boolean hasMessagesOrCallbacks() {
return mQueue.hasMessages(this);
}
以上方法,为【判断是否有】此Handler发出的Message(指定what、obj)、Runnable(指定runnable),全部都是通过调用MessageQueue的hasMessages() 方法进行判断。逻辑同上移除Messages、Runnable。
说明:
1.hasMessagesOrCallbacks():为判断是否有此Handler发出Message、Runnable。
2.hasEqualMessages()、hasMessagesOrCallbacks():两个为@hide方法,只能系统调用。
3.MessageQueue是否有消息相关介绍,请看Android-Handler源码解析-MessageQueue-是否有Message。
小结
- 【判断是否有】此Handler发出
的Message(指定what、obj)、Runnable(指定runnable),全部都是通过调用MessageQueue的hasMessages()方法进行判断。
其它
getMessageName()
public String getMessageName(@NonNull Message message) {
if (message.callback != null) {
// 是Runnable类型,返回此Runnable的类名。
return message.callback.getClass().getName();
}
// 是Message类型,返回此Message的what的十六进制。
return "0x" + Integer.toHexString(message.what);
}
获取表示指定Message名称的字符串。默认实现,是Runnable类型返回此Runnable的类名,是Message类型返回此Message的what的十六进制。
getLooper()
@NonNull
public final Looper getLooper() {
return mLooper;
}
获取此Handler的Looper对象
dump()
public final void dump(@NonNull Printer pw, @NonNull String prefix) {
pw.println(prefix + this + " @ " + SystemClock.uptimeMillis());
if (mLooper == null) {
pw.println(prefix + "looper uninitialized");
} else {
mLooper.dump(pw, prefix + " ");
}
}
转储looper的状态,以进行调试。如果Looper为空,直接打印,否则调用Looper的dump()方法。
说明:
1.Looper转储的相关介绍,请看Android-Handler源码解析-Looper-dump()。
总结
以上就是Handler源码的Handler部分,Handler其它源码部分看下面导航。欢迎大家点赞、收藏,以方便您后续查看,之后会出其它Android源码系列,请及时关注。如果你有什么问题,可以在评论区留言!
导航:
最后推荐一下我的网站,开发者(Developer)的博客(Blog): devblog.cn ,欢迎大家来体验!