Android-Handler源码解析-Handler(一)

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)的影响。

小结

  1. 创建–同步Handler,分为未指定Looper、指定Looper两种方式创建。
    • 未指定Looper,则使用当前线程的Looper,不推荐使用。
    • 指定Looper,推荐使用,构造方法为Handler(Looper)、Handler(Looper, Callback)。
  2. 创建–异步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。

小结

  1. 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对应的发送消息的方法进行发送。

小结

  1. 发送消息分为send-Message、post-Runnable,post-Runnable底层也是通过send-Message进行发送(将Runnable保存到Message的callback中)。
  2. sendMessageAtFrontOfQueue()、postAtFrontOfQueue(),方法为将消息排在消息队列的前面,会使原来有序的队列变为无序的,谨慎使用。
  3. 通过handler发送的消息,最终都会将此Message和此Handler一对一关联,以便此Message由此Handler处理。
  4. 如果此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,所以可以被覆写,一般覆写此方法。

小结

  1. 分发Message,它是通过Handler的dispatchMessage()方法进行分发处理。
  2. 分发Message,它分为处理Runnable、处理Message。
    2.1.处理Runnable,直接调用callback(即Runnable)的run()方法执行。
    2.2.处理Message,优先handler的mCallback处理,其次再handler的handleMessage()方法处理。
  3. 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。

小结

  1. 【移除】此Handler发出的Message(指定what、obj)、Runnable(指定runnable、token),全部都是通过调用MessageQueue的removeXXX方法进行移除。
  2. removeCallbacksAndMessages():参数token如果为空,则删除此Handler发出的所有Runnable和Message。
  3. 带有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。

小结

  1. 【判断是否有】此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 ,欢迎大家来体验!

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇
京ICP备18058279号-1