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 ,欢迎大家来体验!