概述
Looper 分为两部分: 1) Java层的Looper 2) Native层的Looper
Java层的looper主要负责消息队列的控制(消息队列的初始化和启动)。
Native层的Looper主要是消息队列的相关处理, 例如消息队列在Native挂起, 以及其他消息的处理(包括Native层的消息队列, 手动注册的fd相关的epoll监听)
1: Java层的Looper
说到Java层的Looper, 就需要说下Java的线程。
1: 普通的线程
class CommonThread extends Thread {
public void run() {
...
}
}
普通的线程在start之后, 线程执行完run方法之后, 这个线程就自动销毁了。
2: Looper线程
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
带Looper的线程start之后, 线程执行到Looper.loop()方法的时候,由于loop方法其实是一个for (;;)循环, 所以Looper 就会一直在这里循环执行下去。
总结起来, Looper线程其实就是被消息驱动的普通的Java线程, 所以Looper的作用就是管理这个消息队列。
2: Native层的Looper
Native层的Looper使用epoll实现, 它为上层Java层Looper的消息队列实现提供了基础, 而且还提供Native层的消息驱动。
1: Native为上层提供的基础服务
Looper在循环的时候, 不停的调用next方法读取下一条Message.
Looper,java
public static void loop() {
...
for (;;) {
Message msg = queue.next(); // might block
...
}
}
MessageQueue.java
Message next() {
...
for (;;) {
// We can assume mPtr != 0 because the loop is obviously still running.
// The looper will not call this method after the loop quits.
nativePollOnce(mPtr, nextPollTimeoutMillis);
...
}
}
android_os_MessageQueue.cpp
void NativeMessageQueue::pollOnce(JNIEnv* env, int timeoutMillis) {
mInCallback = true;
mLooper->pollOnce(timeoutMillis);
mInCallback = false;
if (mExceptionObj) {
env->Throw(mExceptionObj);
env->DeleteLocalRef(mExceptionObj);
mExceptionObj = NULL;
}
}
Looper.cpp
int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
int result = 0;
for (;;) {
...
if (result != 0) {
if (outFd != NULL) *outFd = 0;
if (outEvents != NULL) *outEvents = 0;
if (outData != NULL) *outData = NULL;
return result;
}
result = pollInner(timeoutMillis);
}
}
int Looper::pollInner(int timeoutMillis) {
...
struct epoll_event eventItems[EPOLL_MAX_EVENTS];
int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
...
return result;
}
这里看到上层的Looper的消息循环其实是由底层的epoll驱动的。
这里通过epoll_wait暂停, 通过Handler.sendMessage()发送消息, 最终唤醒epoll_wait。
Java层发送的消息在Java层处理, Native层的消息在Native层处理。
2: Native层还可以处理的东西
Native层处理的消息都在 pollInner中。
int Looper::pollInner(int timeoutMillis) {
...
struct epoll_event eventItems[EPOLL_MAX_EVENTS];
int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
...
<span style="color:#ff0000;">//Step 1</span>
for (int i = 0; i < eventCount; i++) {
int fd = eventItems[i].data.fd;
uint32_t epollEvents = eventItems[i].events;
if (fd == mWakeReadPipeFd) {
if (epollEvents & EPOLLIN) {
awoken();
} else {
ALOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.", epollEvents);
}
} else {
ssize_t requestIndex = mRequests.indexOfKey(fd);
if (requestIndex >= 0) {
int events = 0;
if (epollEvents & EPOLLIN) events |= ALOOPER_EVENT_INPUT;
if (epollEvents & EPOLLOUT) events |= ALOOPER_EVENT_OUTPUT;
if (epollEvents & EPOLLERR) events |= ALOOPER_EVENT_ERROR;
if (epollEvents & EPOLLHUP) events |= ALOOPER_EVENT_HANGUP;
pushResponse(events, mRequests.valueAt(requestIndex));
} else {
ALOGW("Ignoring unexpected epoll events 0x%x on fd %d that is "
"no longer registered.", epollEvents, fd);
}
}
}
Done: ;
<span style="color:#ff0000;">//Step 2</span>
// Invoke pending message callbacks.
mNextMessageUptime = LLONG_MAX;
while (mMessageEnvelopes.size() != 0) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);
if (messageEnvelope.uptime <= now) {
// Remove the envelope from the list.
// We keep a strong reference to the handler until the call to handleMessage
// finishes. Then we drop it so that the handler can be deleted *before*
// we reacquire our lock.
{ // obtain handler
sp<MessageHandler> handler = messageEnvelope.handler;
Message message = messageEnvelope.message;
mMessageEnvelopes.removeAt(0);
mSendingMessage = true;
mLock.unlock();
#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d",
this, handler.get(), message.what);
#endif
handler->handleMessage(message);
} // release handler
mLock.lock();
mSendingMessage = false;
result = ALOOPER_POLL_CALLBACK;
} else {
// The last message left at the head of the queue determines the next wakeup time.
mNextMessageUptime = messageEnvelope.uptime;
break;
}
}
// Release lock.
mLock.unlock();
<span style="color:#ff0000;">//Step 3</span>
// Invoke all response callbacks.
for (size_t i = 0; i < mResponses.size(); i++) {
Response& response = mResponses.editItemAt(i);
if (response.request.ident == ALOOPER_POLL_CALLBACK) {
int fd = response.request.fd;
int events = response.events;
void* data = response.request.data;
#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
ALOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p",
this, response.request.callback.get(), fd, events, data);
#endif
int callbackResult = response.request.callback->handleEvent(fd, events, data);
if (callbackResult == 0) {
removeFd(fd);
}
// Clear the callback reference in the response structure promptly because we
// will not clear the response vector itself until the next poll.
response.request.callback.clear();
result = ALOOPER_POLL_CALLBACK;
}
}
return result;
}
这部分的逻辑比较简单, 分3部分。
1: 对epoll的事件进行初步处理
2: Native层的消息循环
3: Native层其他注册事件的处理
这部分比较重要, 例如Input部分就利用了这个地方。
1: 客户端注册了epoll(通过Socket实现)并监听。
2: 服务端向客户端Socket的另一端发送事件, 唤醒客户端。
3: 客户端被唤醒后,处理服务端发送的数据。