欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Handler发送消息的过程

程序员文章站 2022-07-14 16:44:10
...

Handler发送消息的过程

当消息队列和消息循环创建好了之后,就可以往消息队列发送消息,定义好msg之后,就通过mHandler.sendMessage(msg)来发送消息

Created with Raphaël 2.1.2HandlerHandlerMessageQueueMessageQueueandorid_os_MessageQueueandorid_os_MessageQueueLooperLoopersendMessageDelayedsendMessageAtTimeenqueueMessageenqueueMessagenativeWakeandroid_os_MessageQueue_nativeWakewakewake

下面具体分析下:
首先从sendMessage开始,然后调用sendMessageDelayed,sendMessageAtTime,enqueueMessage继续处理

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
        msg.target = this;
        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        return queue.enqueueMessage(msg, uptimeMillis);
    }

enqueueMessage()方法首先设置了这个消息的目标处理对象target,即这个消息最终由谁来处理,这里赋值为this,表示这个消息最终由目前发送的Handle来处理,接着enqueueMessage方法调用enqueueMessage方法来把这个消息加入到应用程序的消息队列中去,queue是一个MessageQueue对象

  boolean enqueueMessage(Message msg, long when) {
        synchronized (this) {
            if (mQuitting) {
                IllegalStateException e = new IllegalStateException(
                        msg.target + " sending message to a Handler on a dead thread");
                Log.w(TAG, e.getMessage(), e);
                msg.recycle();
                return false;
            }

            msg.markInUse();
            msg.when = when;
            Message p = mMessages;
            boolean needWake;
            if (p == null || when == 0 || when < p.when) {
                // New head, wake up the event queue if blocked.
                msg.next = p;
                mMessages = msg;
                needWake = mBlocked;
            } else {
                needWake = mBlocked && p.target == null && msg.isAsynchronous();
                Message prev;
                for (;;) {
                    prev = p;
                    p = p.next;
                    if (p == null || when < p.when) {
                        break;
                    }
                    if (needWake && p.isAsynchronous()) {
                        needWake = false;
                    }
                }
                msg.next = p; // invariant: p == prev.next
                prev.next = msg;
            }

            // We can assume mPtr != 0 because mQuitting is false.
            if (needWake) {
                nativeWake(mPtr);
            }
        }
        return true;
    }

enqueueMessage方法中if和else判断,if分支表示目前消息队列为空,这时应用程序主线程处于空闲状态,也就是说它在等待消息的发送,这时如果有消息就把消息放在消息队列的前面,接着唤醒应用程序的主线程。而else分支表示,消息队列不为空,还有消息在处理,这时候不要唤醒应用程序主线程。nativeWake方法是一个native方法,

static void android_os_MessageQueue_nativeWake(JNIEnv* env, jclass clazz, jlong ptr) {
    NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
    nativeMessageQueue->wake();
}
void NativeMessageQueue::wake() {
    mLooper->wake();
}

NativeMessageQueue类的wake函数,又通过调用C++层mLooper对象的wake()函数进一步操作

void Looper::wake() {
#if DEBUG_POLL_AND_WAKE
    ALOGD("%p ~ wake", this);
#endif

    uint64_t inc = 1;
    ssize_t nWrite = TEMP_FAILURE_RETRY(write(mWakeEventFd, &inc, sizeof(uint64_t)));
    if (nWrite != sizeof(uint64_t)) {
        if (errno != EAGAIN) {
            ALOGW("Could not write wake signal, errno=%d", errno);
        }
    }
}

Looper.cpp里的wake()函数通过如下代码调用:
ssize_t nWrite = TEMP_FAILURE_RETRY(write(mWakeEventFd, &inc, sizeof(uint64_t)));
write()函数,mWakeEventFd就发生了一个event事件,这时前面监听的epoll机制就起了作用,会唤醒应用程序主线程,于是应用程序主线程就会从前面的C++层的Looper类的polllner()函数一层层返回,最后返回到java层的MessageQueue类的next()方法中
发送消息就介绍完了,创建消息对列和消息循环可参考上一篇文章