在多线程编程中,线程的等待机制是确保程序正确执行的关键。特别是在Android开发中,handler机制是处理后台任务和更新UI的重要手段。本文将深入解析handler进程与线程的等待机制,帮助开发者更好地理解和应用这一机制。
1. 什么是handler?
handler是Android中用于处理消息和事件的机制。它允许我们在不同的线程中发送和处理消息,而无需直接在主线程(UI线程)中执行耗时操作。handler通常与Looper和MessageQueue一起使用,形成一个消息循环。
2. handler的工作原理
handler的工作原理可以概括为以下几个步骤:
- 创建一个Looper对象,用于创建一个消息循环。
- 创建一个handler对象,绑定到Looper。
- 在后台线程中执行耗时操作,并将结果封装成Message对象。
- 使用handler的sendMessage方法将Message对象发送到MessageQueue。
- Looper从MessageQueue中取出Message,并调用handler的handleMessage方法处理消息。
3. 线程的等待机制
在handler机制中,线程的等待机制主要体现在以下几个方面:
3.1 Looper的循环
Looper的循环是handler机制的核心。它不断地从MessageQueue中取出Message,并调用handler的handleMessage方法处理消息。当MessageQueue中没有消息时,Looper会进入等待状态,直到有新的消息到来。
public final void loop() {
for (int i = 0; i < MSG_LOOPS; i++) {
Message msg = queue.next(); // might block
if (msg == null) {
// Check if we have lost our queue because the application went away and our thread got garbage collected.
if (handleMessageLoopException(null)) {
continue;
} else {
return;
}
}
msg.target.dispatchMessage(msg);
if (msg.isAsynchronous()) {
continue;
}
}
}
3.2 MessageQueue的等待
MessageQueue是一个线程安全的队列,用于存储消息。当MessageQueue中没有消息时,Looper会进入等待状态,直到有新的消息到来。
public final Message next() {
for (;;) {
synchronized (this) {
// Return immediately if the queue is empty.
if (msgCount == 0 && nextPollTimeoutMillis != 0) {
return null;
}
final long now = SystemClock.elapsedRealtime();
if (nextPollTimeoutMillis <= 0) {
// No timeout - wait forever.
nextPollTimeoutMillis = Long.MAX_VALUE;
} else {
// Have an explicit timeout - wait at most nextPollTimeoutMillis.
final long timeoutAt = nextPollTimeoutMillis + now;
while (msgCount == 0) {
if (nextPollTimeoutMillis != Long.MAX_VALUE) {
long remaining = timeoutAt - now;
if (remaining <= 0) {
// Next poll should happen immediately.
nextPollTimeoutMillis = 0;
continue;
}
// -19 priority gives that thread priority to time out sooner if the application becomes
// hung trying to finish up all its enqueued messages and is holding onto the Looper.
MessageQueue.nativePollOnce(queueId, remaining - now, -19);
}
nextPollTimeoutMillis = 0;
nativePollOnce(queueId);
}
}
Message msg = queue.remove(0);
msg.markInUse();
msg.markSystemTargetAccess();
return msg;
}
}
}
3.3 handler的sendMessage
handler的sendMessage方法用于将消息发送到MessageQueue。如果MessageQueue中没有消息,sendMessage会立即返回。如果MessageQueue中有消息,sendMessage会等待消息被处理后再返回。
public final boolean sendMessage(Message msg) {
return sendMessageAtTime(msg, SystemClock.elapsedRealtime());
}
public final boolean sendMessageAtTime(Message msg, long when) {
MessageQueue queue = mLooper.mQueue;
if (msg.target == null) {
msg.target = this;
}
if (when == 0) {
return queue.enqueueMessage(msg, 0);
} else {
return queue.enqueueMessageAtTime(msg, when);
}
}
4. 总结
handler进程与线程的等待机制是Android开发中处理并发和异步任务的重要手段。通过深入理解Looper、MessageQueue和handler的工作原理,我们可以更好地利用这一机制,提高应用程序的性能和稳定性。
