一 概述
在 Android消息机制1 (Java层) 中我们分析了 Java 层的消息处理机制,其中 MessageQueue 类里面涉及到多个 native 方法,除了 MessageQueue 的 native 方法,native 层本身也有一套完整的消息机制,用于处理 native 的消息,如下图 Native 层的消息机制。
在整个消息机制中,MessageQueue 是连接 Java 层和 Native 层的纽带,换言之,Java 层可以向 MessageQueue 消息队列中添加消息,Native 层也可以向 MessageQueue 消息队列中添加消息,接下来来看看 MessageQueue。
相关代码
framework/base/core/java/andorid/os/MessageQueue.java
framework/base/core/jni/android_os_MessageQueue.cpp
framework/base/core/java/andorid/os/Looper.java
system/core/libutils/Looper.cpp
system/core/include/utils/Looper.h
system/core/libutils/RefBase.cpp
framework/base/native/android/looper.cpp
framework/native/include/android/looper.h
二 MessageQueue
在 MessageQueue 中的 native 方法如下:
private native static long nativeInit();
private native static void nativeDestroy(long ptr);
private native void nativePollOnce(long ptr, int timeoutMillis);
private native static void nativeWake(long ptr);
private native static boolean nativeIsPolling(long ptr);
private native static void nativeSetFileDescriptorEvents(
long ptr, int fd, int events);
2.1 nativeInit()
初始化过程的调用链如下:
下面来进一步来看看调用链的过程:
1.new MessageQueue()
MessageQueue.java
MessageQueue(boolean quitAllowed) {
mQuitAllowed = quitAllowed;
mPtr = nativeInit(); //mPtr记录native消息队列的信息
}
2.android_os_MessageQueue_nativeInit()
android_os_MessageQueue.cpp
static jlong android_os_MessageQueue_nativeInit(JNIEnv* env, jclass clazz) {
//初始化native消息队列
NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue();
nativeMessageQueue->incStrong(env); //增加引用计数
return reinterpret_cast<jlong>(nativeMessageQueue);
}
此处 reinterpret_cast 是 C++ 里的强制类型转换符
3.new NativeMessageQueue()
android_os_MessageQueue.cpp
NativeMessageQueue::NativeMessageQueue()
: mPollEnv(NULL), mPollObj(NULL), mExceptionObj(NULL) {
mLooper = Looper::getForThread(); //获取TLS中的Looper对象
if (mLooper == NULL) {
mLooper = new Looper(false); //创建native层的Looper
Looper::setForThread(mLooper); //保存native层的Looper到TLS
}
}
- Looper::getForThread(),功能类比于 Java 层的 Looper.myLooper()
- Looper::setForThread(mLooper),功能类比于 Java 层的 ThreadLocal.set()
此处 Native 层的 Looper 与 Java 层的 Looper 没有任何的关系,只是在 Native 层重实现了一套类似功能的逻辑。
4.new Looper()
Looper.cpp
Looper::Looper(bool allowNonCallbacks) :
mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false),
mPolling(false), mEpollFd(-1), mEpollRebuildRequired(false),
mNextRequestSeq(0), mResponseIndex(0), mNextMessageUptime(LLONG_MAX) {
//构造唤醒事件的fd
mWakeEventFd.reset(eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC));
AutoMutex _l(mLock);
rebuildEpollLocked(); //重建Epoll事件
}
5.epoll_create/epoll_ctl
Looper.cpp
void Looper::rebuildEpollLocked() {
if (mEpollFd >= 0) {
close(mEpollFd); //关闭旧的epoll实例
}
mEpollFd = epoll_create(EPOLL_SIZE_HINT); //创建新的epoll实例,并注册wake管道
struct epoll_event eventItem;
memset(& eventItem, 0, sizeof(epoll_event)); //把未使用的数据区域进行置0操作
eventItem.events = EPOLLIN; //可读事件
eventItem.data.fd = mWakeEventFd;
//将唤醒事件(mWakeEventFd)添加到epoll实例(mEpollFd)
int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeEventFd, & eventItem);
for (size_t i = 0; i < mRequests.size(); i++) {
const Request& request = mRequests.valueAt(i);
struct epoll_event eventItem;
request.initEventItem(&eventItem);
//将request队列的事件,分别添加到epoll实例
int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, request.fd, & eventItem);
}
}