JNINativeMethod结构体及 系统 JNI 接口的注册流程

来源:互联网 发布:淘宝直邮靠谱吗 编辑:程序博客网 时间:2024/05/08 18:50

zygote进程在启动ART虚拟机后,会有一个注册系统JNI接口的调用:

AndroidRuntime::start()中: 

..... if (startVm(&mJavaVM, &env) != 0) {        return;    }    onVmCreated(env);    /*     * Register android functions.     */    if (startReg(env) < 0) {        ALOGE("Unable to register all android natives\n");        return;    }....

startReg(env)即是进行系统JNI接口的注册.

    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {        env->PopLocalFrame(NULL);        return -1;    }

gRegJNI的定义如下:

static const RegJNIRec gRegJNI[] = {    REG_JNI(register_com_android_internal_os_RuntimeInit),    ......    REG_JNI(register_android_os_Process),    ......}

register_jni_procs()的实现:

static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env){    for (size_t i = 0; i < count; i++) {        if (array[i].mProc(env) < 0) {            ......        }    }    return 0;}

startReg(), 调用register_jni_procs(), 通过for循环,遍历调用gRegJNI数组中的函数(通过指向函数的指针实现).

 

关于gRegJNI:

可以看到, gRegJNI是一个成员为RegJNIRec类型的数组.RegJNIRec的定义如下:

#ifdef NDEBUG    #define REG_JNI(name)      { name }    struct RegJNIRec {        int (*mProc)(JNIEnv*);    };#else    #define REG_JNI(name)      { name, #name }    struct RegJNIRec {        int (*mProc)(JNIEnv*);        const char* mName;    };#endif

根据代码推断,宏开关NDEBUG是打开的,即RegJNIRec的实际定义为:

    #define REG_JNI(name)      { name }    struct RegJNIRec {        int (*mProc)(JNIEnv*);    };

即,RegJNIRec是一个结构体,该结构体有一个指向函数的指针成员,且该指针指向的函数的参数类型为:JNIEnv*.

再看 gRegJNI[] 数组的一个成员:REG_JNI(register_android_os_Process),REG_JNI为宏定义, 宏替换后的代码应该为:

{ register_android_os_Process}


上面已经分析, 注册的过程,就是通过遍历gRegJNI[] 数组,调用其成员中的函数指针指向的函数来实现. 而:

{ register_android_os_Process}

就是其中的结构体的成员,该结构体的唯一的成员为一个函数指针:register_android_os_Process,跟踪代码,该函数位于android_util_Process.cpp中,完整定义:

int register_android_os_Process(JNIEnv* env){    return RegisterMethodsOrDie(env, "android/os/Process", methods, NELEM(methods));}
static inline int RegisterMethodsOrDie(JNIEnv* env, const char* className,                                       const JNINativeMethod* gMethods, int numMethods) {    int res = AndroidRuntime::registerNativeMethods(env, className, gMethods, numMethods);    LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");    return res;}

根据文件名(android_util_Process)可以推断,该函数注册的是Process相关的JNI接口, 具体哪些接口,由RegisterMethodsOrDie()的参数:methods指定.显然, methods是一个结构体数组,且对应的结构体,就是  文章标题中提到的结构体: JNINativeMethod. 

 

该结构体对应一个JNI方法的相关信息

typedef struct {    const char* name;     // java层对应的方法名称    const char* signature;// 该方法的返回值类型和参数类型    void*       fnPtr;    // native中对应的函数指针} JNINativeMethod;

 

android_util_Process指定的结构体数组 methods为:

static const JNINativeMethod methods[] = {    {"getUidForName",       "(Ljava/lang/String;)I", (void*)android_os_Process_getUidForName},    {"getGidForName",       "(Ljava/lang/String;)I", (void*)android_os_Process_getGidForName},    {"setThreadPriority",   "(II)V", (void*)android_os_Process_setThreadPriority},    {"setThreadScheduler",  "(III)V", (void*)android_os_Process_setThreadScheduler},    {"setCanSelfBackground", "(Z)V", (void*)android_os_Process_setCanSelfBackground},    {"setThreadPriority",   "(I)V", (void*)android_os_Process_setCallingThreadPriority},    {"getThreadPriority",   "(I)I", (void*)android_os_Process_getThreadPriority},    {"setThreadGroup",      "(II)V", (void*)android_os_Process_setThreadGroup},    {"setProcessGroup",     "(II)V", (void*)android_os_Process_setProcessGroup},    {"getProcessGroup",     "(I)I", (void*)android_os_Process_getProcessGroup},    {"setSwappiness",   "(IZ)Z", (void*)android_os_Process_setSwappiness},    {"setArgV0",    "(Ljava/lang/String;)V", (void*)android_os_Process_setArgV0},    {"setUid", "(I)I", (void*)android_os_Process_setUid},    {"setGid", "(I)I", (void*)android_os_Process_setGid},    {"sendSignal", "(II)V", (void*)android_os_Process_sendSignal},    {"sendSignalQuiet", "(II)V", (void*)android_os_Process_sendSignalQuiet},    {"getFreeMemory", "()J", (void*)android_os_Process_getFreeMemory},    {"getTotalMemory", "()J", (void*)android_os_Process_getTotalMemory},    {"readProcLines", "(Ljava/lang/String;[Ljava/lang/String;[J)V", (void*)android_os_Process_readProcLines},    {"getPids", "(Ljava/lang/String;[I)[I", (void*)android_os_Process_getPids},    {"readProcFile", "(Ljava/lang/String;[I[Ljava/lang/String;[J[F)Z", (void*)android_os_Process_readProcFile},    {"parseProcLine", "([BII[I[Ljava/lang/String;[J[F)Z", (void*)android_os_Process_parseProcLine},    {"getElapsedCpuTime", "()J", (void*)android_os_Process_getElapsedCpuTime},    {"getPss", "(I)J", (void*)android_os_Process_getPss},    {"getPidsForCommands", "([Ljava/lang/String;)[I", (void*)android_os_Process_getPidsForCommands},    //{"setApplicationObject", "(Landroid/os/IBinder;)V", (void*)android_os_Process_setApplicationObject},    {"killProcessGroup", "(II)I", (void*)android_os_Process_killProcessGroup},    {"removeAllProcessGroups", "()V", (void*)android_os_Process_removeAllProcessGroups},};

以上便可以看到该接口注册了哪些jni接口,相关接口在Java层便可通过jni调用,有些还是很眼熟的.

最终的注册工作,是调用 AndroidRuntime.registerNativeMethods(env, className, gmethods,  numMethods)来实现。

系统JNI接口的注册流程大致就是上面所述.

0 0
原创粉丝点击