Android MessageQueue 源码分析

类注释

/**
 * Low-level class holding the list of messages to be dispatched by a
 * {@link Looper}.  Messages are not added directly to a MessageQueue,
 * but rather through {@link Handler} objects associated with the Looper.
 *
 * <p>You can retrieve the MessageQueue for the current thread with
 * {@link Looper#myQueue() Looper.myQueue()}.
 */

MessageQueue 类是 Android 系统中用于管理消息队列的一个低级类,它持有将要由 Looper 分发的消息列表。在 Android 的消息处理机制中,消息并不是直接添加到 MessageQueue 中的,而是通过与 Looper 相关联的 Handler 对象来添加的。
如果你想要获取当前线程(比如主线程)的 MessageQueue,你可以使用 Looper.myQueue() 方法。这个方法会返回与当前线程关联的 Looper 对象的 MessageQueue,如果当前线程没有 Looper,则会抛出 RuntimeException

成员变量

mQuitAllowed
    // True if the message queue can be quit.
    @UnsupportedAppUsage
    private final boolean mQuitAllowed;

是否允许message queue退出。

mPtr
    @UnsupportedAppUsage
    @SuppressWarnings("unused")
    private long mPtr; // used by native code

native MessageQueue的指针变量

mMessages
    @UnsupportedAppUsage
    Message mMessages;

Message Queue消息队列的队首指针,即消息队列最前面的元素。

mIdleHandlers
    @UnsupportedAppUsage
    private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>();

IdleHandler列表,用来记录需要进行callback回调的IdleHandler对象

mFileDescriptorRecords
    private SparseArray<FileDescriptorRecord> mFileDescriptorRecords;

mFileDescriptorRecords为存储文件描述符的map数据结构

mPendingIdleHandlers
    private IdleHandler[] mPendingIdleHandlers;

处于等待的IdleHandler类型的数组

mQuitting
    private boolean mQuitting;

消息队列正在退出

mBlocked
    // Indicates whether next() is blocked waiting in pollOnce() with a non-zero timeout.
    private boolean mBlocked;

指出是否next()被阻塞在了一个携带着非0超时参数的pollOnce() 上。

mNextBarrierToken
    // The next barrier token.
    // Barriers are indicated by messages with a null target whose arg1 field carries the token.
    @UnsupportedAppUsage
    private int mNextBarrierToken;

表示下一个屏障(Barrier)的令牌(Token)

nativeInit
    private native static long nativeInit();

用于初始化native层的message queue.

nativeDestroy
    private native static void nativeDestroy(long ptr);

用于销毁native层的message queue

nativePollOnce
    @UnsupportedAppUsage
    private native void nativePollOnce(long ptr, int timeoutMillis); /*non-static for callbacks*/

等待timeoutMillis获取下一个消息

nativeWake
    private native static void nativeWake(long ptr);

native部分,我们再讲

nativeIsPolling
    private native static boolean nativeIsPolling(long ptr);

native部分,我们再讲

nativeSetFileDescriptorEvents
    private native static void nativeSetFileDescriptorEvents(long ptr, int fd, int events);

native部分,我们再讲

MessageQueue 构造函数
    MessageQueue(boolean quitAllowed) {
        mQuitAllowed = quitAllowed;
        mPtr = nativeInit();
    }
  1. MessageQueue创建的时候,会设置mQuitAllowed的值,告知是否允许退出。
  2. 创建native层的MessageQueue
finalize
    @Override
    protected void finalize() throws Throwable {
        try {
            dispose();
        } finally {
            super.finalize();
        }
    }

finalize() 方法是一个在对象被垃圾回收器回收之前调用的方法。

dispose
    // Disposes of the underlying message queue.
    // Must only be called on the looper thread or the finalizer.
    private void dispose() {
        if (mPtr != 0) {
            nativeDestroy(mPtr);
            mPtr = 0;
        }
    }

处理底层的message queue,即销毁native层的message queue。

isIdle
    /**
     * Returns true if the looper has no pending messages which are due to be processed.
     *
     * <p>This method is safe to call from any thread.
     *
     * @return True if the looper is idle.
     */
    public boolean isIdle() {
        synchronized (this) {
            final long now = SystemClock.uptimeMillis();
            return mMessages == null || now < mMessages.when;
        }
    }

它检查循环器是否有任何即将被处理的挂起消息。如果循环器当前没有待处理的消息,或者所有待处理的消息的执行时间都晚于当前时间(即它们还没有到被处理的时机),则该方法返回 true,表示循环器当前是空闲的。

addIdleHandler
    /**
     * Add a new {@link IdleHandler} to this message queue.  This may be
     * removed automatically for you by returning false from
     * {@link IdleHandler#queueIdle IdleHandler.queueIdle()} when it is
     * invoked, or explicitly removing it with {@link #removeIdleHandler}.
     *
     * <p>This method is safe to call from any thread.
     *
     * @param handler The IdleHandler to be added.
     */
    public void addIdleHandler(@NonNull IdleHandler handler) {
        if (handler == null) {
            throw new NullPointerException("Can't add a null IdleHandler");
        }
        synchronized (this) {
            mIdleHandlers.add(handler);
        }
    }

用于向消息队列中添加一个新的 IdleHandler。IdleHandler 是一个接口,用于在消息队列空闲时执行某些操作。通过添加 IdleHandler,开发者可以在消息队列没有待处理消息时执行自定义的空闲处理逻辑。
IdleHandler 可以通过在 IdleHandler.queueIdle() 方法中返回 false 来自动从消息队列中移除。这是因为在消息队列的空闲处理循环中,会遍历 mIdleHandlers 集合,并调用每个 IdleHandler 的 queueIdle() 方法。如果该方法返回 false,则表示该 IdleHandler 不再需要被调用,因此会从集合中移除。

removeIdleHandler
    /**
     * Remove an {@link IdleHandler} from the queue that was previously added
     * with {@link #addIdleHandler}.  If the given object is not currently
     * in the idle list, nothing is done.
     *
     * <p>This method is safe to call from any thread.
     *
     * @param handler The IdleHandler to be removed.
     */
    public void removeIdleHandler(@NonNull IdleHandler handler) {
        synchronized (this) {
            mIdleHandlers.remove(handler);
        }
    }

可以通过调用 removeIdleHandler 方法来显式地从消息队列中移除 IdleHandler.

isPolling
    /**
     * Returns whether this looper's thread is currently polling for more work to do.
     * This is a good signal that the loop is still alive rather than being stuck
     * handling a callback.  Note that this method is intrinsically racy, since the
     * state of the loop can change before you get the result back.
     *
     * <p>This method is safe to call from any thread.
     *
     * @return True if the looper is currently polling for events.
     * @hide
     */
    public boolean isPolling() {
        synchronized (this) {
            return isPollingLocked();
        }
    }

用于检查这个循环器(Looper)的线程当前是否在轮询(polling)以寻找更多的工作要做。这个方法是一个有用的信号,表明循环器仍在活跃状态,而不是在处理某个回调时被卡住.

isPollingLocked
    private boolean isPollingLocked() {
        // If the loop is quitting then it must not be idling.
        // We can assume mPtr != 0 when mQuitting is false.
        return !mQuitting && nativeIsPolling(mPtr);
    }

该方法用于在同步或受保护的上下文中检查循环器(Looper)是否正在轮询(polling)事件。首先,方法检查 mQuitting 标志。如果 mQuitting 为 true,则表示循环器正在退出过程中,此时它不可能处于空闲轮询状态。因此,在这种情况下,方法会立即返回 false。其次,通过nativeIsPolling检查native层的循环器(Looper)是否正在轮询(polling)事件。只有java层和native层都处于轮询事件的状态,isPollingLocked才会返回true,否则返回false。

addOnFileDescriptorEventListener
    /**
     * Adds a file descriptor listener to receive notification when file descriptor
     * related events occur.
     * <p>
     * If the file descriptor has already been registered, the specified events
     * and listener will replace any
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值