在Binder机制的架构中,分为Java Binder和Native Binder。Java层的Binder可以说是Native层的Binder的镜像,而Java Binder这个镜像归根结底还是依赖Native Binder层的运转,那么Java Binder要和Native Binder肯定需要建立某种联系进行通信,这种联系就是通过JNI,
初始化Java Binder框架 JNI的注册是在Zygote进程启动过程中进行的,代码如下所示:
frameworks/base/core/jni/AndroidRuntime.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 void AndroidRuntime::start (const char * className, const Vector<String8>& options, bool zygote) { JniInvocation jni_invocation; jni_invocation.Init (NULL ); JNIEnv* env; if (startVm (&mJavaVM, &env, zygote) != 0 ) { return ; } onVmCreated (env); if (startReg (env) < 0 ) { ALOGE ("Unable to register all android natives\n" ); return ; } }
在注释1出开启Java虚拟机,并在注释2出调用startReg注册android JNI 函数。进入到startReg函数内看看到底是如何完成JNI的注册的。
frameworks/base/core/jni/AndroidRuntime.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 int AndroidRuntime::startReg (JNIEnv* env) { ATRACE_NAME ("RegisterAndroidNatives" ); androidSetCreateThreadFunc ((android_create_thread_fn) javaCreateThreadEtc); ALOGV ("--- registering native functions ---\n" ); env->PushLocalFrame (200 ); if (register_jni_procs (gRegJNI, NELEM (gRegJNI), env) < 0 ) { env->PopLocalFrame (NULL ); return -1 ; } env->PopLocalFrame (NULL ); return 0 ; }
函数的注释说明的很清楚,向虚拟机注册android native函数,通过register_jni_procs函数循环的调用gRegJNI数组的数组所对应的方法,如下所示:
frameworks/base/core/jni/AndroidRuntime.cpp
1 2 3 4 5 6 7 8 9 10 11 12 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 ) { #ifndef NDEBUG ALOGD ("----------!!! %s failed to load\n" , array[i].mName); #endif return -1 ; } } return 0 ; }
gRegJNI数组有一百多个成员变量,只截取Binder相关的类:
1 2 3 4 5 static const RegJNIRec gRegJNI[] = { REG_JNI (register_android_os_Binder), };
REG_JNI是个宏定义:
1 2 3 4 #define REG_JNI(name) { name } struct RegJNIRec { int (*mProc)(JNIEnv*); };
展开后其实就是调用参数名所对应的函数。所以负责Java Binder和Native Binder通信的函数为register_android_os_Binder,代码如下:
frameworks/base/core/jni/android_util_Binder.cpp
1 2 3 4 5 6 7 8 9 10 11 12 int register_android_os_Binder (JNIEnv* env) { if (int_register_android_os_Binder (env) < 0 ) return -1 ; if (int_register_android_os_BinderInternal (env) < 0 ) return -1 ; if (int_register_android_os_BinderProxy (env) < 0 ) return -1 ; return 0 ; }
register_android_os_Binder函数有三个作用:注册Binder类、注册BonderInternal类和注册BinderPorxy类,它们是Java Binder中的关联类。
1- Binder类的初始化 调用int_register_android_os_Binder函数完成Binder累的初始化工作,代码如下:
frameworks/base/core/jni/android_util_Binder.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 const char * const kBinderPathName = "android/os/Binder" ;static int int_register_android_os_Binder (JNIEnv* env) { jclass clazz = FindClassOrDie (env, kBinderPathName); gBinderOffsets.mClass = MakeGlobalRefOrDie (env, clazz); gBinderOffsets.mExecTransact = GetMethodIDOrDie (env, clazz, "execTransact" , "(IJJI)Z" ); gBinderOffsets.mObject = GetFieldIDOrDie (env, clazz, "mObject" , "J" ); return RegisterMethodsOrDie ( env, kBinderPathName, gBinderMethods, NELEM (gBinderMethods)); }
gBinderOffsets的定义如下:
1 2 3 4 5 6 7 8 9 10 static struct bindernative_offsets_t { jclass mClass; jmethodID mExecTransact; jfieldID mObject; } gBinderOffsets;
由int_register_android_os_Binder函数可知,使用gBinderOffsets对象保存Binder类的函数和成员变量,那日后将可用来在JNI层对Java层的Binder对象进行操作。在int_register_android_os_Binder函数最后一行通过RegisterMethodsOrDie函数注册gBinderMethods定义的函数,其中gBinderMethods是JNINativeMehtod类型的数组,存储了Jave 层Binder的Native方法和JNI层函数的对应关系,如果不是很清楚JNI的机制,可自行查阅。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 static const JNINativeMethod gBinderMethods[] = { { "getCallingPid" , "()I" , (void *)android_os_Binder_getCallingPid }, { "getCallingUid" , "()I" , (void *)android_os_Binder_getCallingUid }, { "clearCallingIdentity" , "()J" , (void *)android_os_Binder_clearCallingIdentity }, { "restoreCallingIdentity" , "(J)V" , (void *)android_os_Binder_restoreCallingIdentity }, { "setThreadStrictModePolicy" , "(I)V" , (void *)android_os_Binder_setThreadStrictModePolicy }, { "getThreadStrictModePolicy" , "()I" , (void *)android_os_Binder_getThreadStrictModePolicy }, { "flushPendingCommands" , "()V" , (void *)android_os_Binder_flushPendingCommands }, { "getNativeBBinderHolder" , "()J" , (void *)android_os_Binder_getNativeBBinderHolder }, { "getNativeFinalizer" , "()J" , (void *)android_os_Binder_getNativeFinalizer }, { "blockUntilThreadAvailable" , "()V" , (void *)android_os_Binder_blockUntilThreadAvailable } };
2- BinderInternal类的初始化 调用int_register_android_os_BinderInternal函数来完成BinderInternal类的初始化,代码如下:
frameworks/base/core/jni/android_util_Binder.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 const char * const kBinderInternalPathName = "com/android/internal/os/BinderInternal" ;static int int_register_android_os_BinderInternal (JNIEnv* env) { jclass clazz = FindClassOrDie (env, kBinderInternalPathName); gBinderInternalOffsets.mClass = MakeGlobalRefOrDie (env, clazz); gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie (env, clazz, "forceBinderGc" , "()V" ); gBinderInternalOffsets.mProxyLimitCallback = GetStaticMethodIDOrDie (env, clazz, "binderProxyLimitCallbackFromNative" , "(I)V" ); jclass SparseIntArrayClass = FindClassOrDie (env, "android/util/SparseIntArray" ); gSparseIntArrayOffsets.classObject = MakeGlobalRefOrDie (env, SparseIntArrayClass); gSparseIntArrayOffsets.constructor = GetMethodIDOrDie (env, gSparseIntArrayOffsets.classObject, "<init>" , "()V" ); gSparseIntArrayOffsets.put = GetMethodIDOrDie (env, gSparseIntArrayOffsets.classObject, "put" , "(II)V" ); BpBinder::setLimitCallback (android_os_BinderInternal_proxyLimitcallback); return RegisterMethodsOrDie ( env, kBinderInternalPathName, gBinderInternalMethods, NELEM (gBinderInternalMethods)); }
和BinderInternal类初始化类似,只不过是保存在gBinderInternalOffsets结构体中,函数的最后一行也是注册BinderInternal类中的Native方法。
3- BinderProxy类的初始化 调用int_register_android_os_BinderProxy函数完成BinderProxy的初始化,代码如下所示:
frameworks/base/core/jni/android_util_Binder.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 const char * const kBinderProxyPathName = "android/os/BinderProxy" ;static int int_register_android_os_BinderProxy (JNIEnv* env) { jclass clazz = FindClassOrDie (env, "java/lang/Error" ); gErrorOffsets.mClass = MakeGlobalRefOrDie (env, clazz); clazz = FindClassOrDie (env, kBinderProxyPathName); gBinderProxyOffsets.mClass = MakeGlobalRefOrDie (env, clazz); gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie (env, clazz, "getInstance" , "(JJ)Landroid/os/BinderProxy;" ); gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie (env, clazz, "sendDeathNotice" , "(Landroid/os/IBinder$DeathRecipient;)V" ); gBinderProxyOffsets.mDumpProxyDebugInfo = GetStaticMethodIDOrDie (env, clazz, "dumpProxyDebugInfo" , "()V" ); gBinderProxyOffsets.mNativeData = GetFieldIDOrDie (env, clazz, "mNativeData" , "J" ); clazz = FindClassOrDie (env, "java/lang/Class" ); gClassOffsets.mGetName = GetMethodIDOrDie (env, clazz, "getName" , "()Ljava/lang/String;" ); return RegisterMethodsOrDie ( env, kBinderProxyPathName, gBinderProxyMethods, NELEM (gBinderProxyMethods)); }
BinderProxy类的初始化,gBinderProxyOffsets结构体中保存了BinderProxy类的相关信息。
到这里Java Binder几个重要成员的初始化都已完成,同时在代码定义了几个全局的静态变量对象,分别是gBinderOffsets、gBinderInternalOffsets和gBinderProxyOffsets。
框架的初始化过程就是获取了一些JNI层需要使用的信息,比如类成员函数的methodID、类成员变量的fileID。之所以这么处理是避免以后每次使用Binder的时候都需要频繁的调用。