Handler发送消息的过程
Handler发送消息的过程
当消息队列和消息循环创建好了之后,就可以往消息队列发送消息,定义好msg之后,就通过mHandler.sendMessage(msg)来发送消息
下面具体分析下:
首先从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()方法中
发送消息就介绍完了,创建消息对列和消息循环可参考上一篇文章
推荐阅读
-
使用Python的Zato发送AMQP消息的教程
-
记一次mq无法正常生产消息的事故排查过程
-
RocketMQ中Producer消息的发送
-
MYSQL存储过程中事务和DECLARE EXIT/CONTINUE HANDLER的使用
-
微信公共服务平台开发(.Net 的实现)3-------发送文本消息
-
微信公共服务平台开发(.Net 的实现)7-------发送图文消息
-
记录一次排查使用HttpWebRequest发送请求的发生“基础连接已关闭:接收时发生错误”异常问题的过程
-
消息持续发送的完整例子
-
C#开发微信门户及应用(19)-微信企业号的消息发送(文本、图片、文件、语音、视频、图文消息等)
-
python 发送和接收ActiveMQ消息的实例