Android消息机制2 (Native层)

一 概述

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);
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值