Java Binder的JNI注册

在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)
{
//...

/* start the virtual machine */
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote) != 0) {//1 开启java 虚拟机
return;
}
onVmCreated(env);

/*
* Register android functions.
*/
if (startReg(env) < 0) {//注册Android 函数
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
/*
* Register android native functions with the VM.
*/
/*static*/ int AndroidRuntime::startReg(JNIEnv* env)
{
ATRACE_NAME("RegisterAndroidNatives");
/*
* This hook causes all future threads created in this process to be
* attached to the JavaVM. (This needs to go away in favor of JNI
* Attach calls.)
*/
androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);

ALOGV("--- registering native functions ---\n");

/*
* Every "register" function calls one or more things that return
* a local reference (e.g. FindClass). Because we haven't really
* started the VM yet, they're all getting stored in the base frame
* and never released. Use Push/Pop to manage the storage.
*/
env->PushLocalFrame(200);

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

//createJavaThread("fubar", quickTest, (void*) "hello");

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 BinderNative 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)//注册Binder类
return -1;
if (int_register_android_os_BinderInternal(env) < 0)//注册BonderInternal类
return -1;
if (int_register_android_os_BinderProxy(env) < 0)//注册BinderPorxy类
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)
{
//kBinderPathName为Java层中Binder类的全路径名:
jclass clazz = FindClassOrDie(env, kBinderPathName);
//gBinderOffsets是一个静态类对象,用来保存Binder类的一些JNI层中使用的信息
gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
//比如Binder类的execTransact函数的methodID
gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
//比如Binder类的mObject函数的fileID
gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
//注册Binder类中native函数的实现
return RegisterMethodsOrDie(
env, kBinderPathName,
gBinderMethods, NELEM(gBinderMethods));
}

gBinderOffsets的定义如下:

1
2
3
4
5
6
7
8
9
10
static struct bindernative_offsets_t
{
// Class state.
jclass mClass;
jmethodID mExecTransact;

// Object state.
jfieldID mObject;

} gBinderOffsets;

int_register_android_os_Binder函数可知,使用gBinderOffsets对象保存Binder类的函数和成员变量,那日后将可用来在JNI层对Java层的Binder对象进行操作。在int_register_android_os_Binder函数最后一行通过RegisterMethodsOrDie函数注册gBinderMethods定义的函数,其中gBinderMethodsJNINativeMehtod类型的数组,存储了Jave 层Binder的Native方法和JNI层函数的对应关系,如果不是很清楚JNI的机制,可自行查阅。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
static const JNINativeMethod gBinderMethods[] = {
/* name, signature, funcPtr */
{ "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)
{
//kBinderInternalPathName为BinderInternal类全路径
jclass clazz = FindClassOrDie(env, kBinderInternalPathName);
//gBinderInternalOffsets用来保存BinderInternal类的一些信息
gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
//获取BinderInternal类forceBinderGc方法methodId
gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");
//获取BinderInternal类fbinderProxyLimitCallbackFromNative方法methodId
gBinderInternalOffsets.mProxyLimitCallback = GetStaticMethodIDOrDie(env, clazz, "binderProxyLimitCallbackFromNative", "(I)V");

//存放SparseIntArray类相关信息
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);
//注册BinderInternal类中的Native方法
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);
//kBinderProxyPathName BinderProxy类的全路径名
clazz = FindClassOrDie(env, kBinderProxyPathName);
//gBinderProxyOffsets用来存储BinderProxy类的一些信息
gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
//获取BinderProxy类的getInstance函数methodID
gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, clazz, "getInstance",
"(JJ)Landroid/os/BinderProxy;");
// 获取BinderProxy类的sendDeathNotice函数methodID
gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
"(Landroid/os/IBinder$DeathRecipient;)V");
// 获取BinderProxy类的dumpProxyDebugInfo函数methodID
gBinderProxyOffsets.mDumpProxyDebugInfo = GetStaticMethodIDOrDie(env, clazz, "dumpProxyDebugInfo",
"()V");
//获取BinderProxy类的mNativeData成员变量的fileID
gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J");

clazz = FindClassOrDie(env, "java/lang/Class");
gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
//注册BinderProxy类中的Native函数
return RegisterMethodsOrDie(
env, kBinderProxyPathName,
gBinderProxyMethods, NELEM(gBinderProxyMethods));
}

BinderProxy类的初始化,gBinderProxyOffsets结构体中保存了BinderProxy类的相关信息。

到这里Java Binder几个重要成员的初始化都已完成,同时在代码定义了几个全局的静态变量对象,分别是gBinderOffsetsgBinderInternalOffsetsgBinderProxyOffsets

框架的初始化过程就是获取了一些JNI层需要使用的信息,比如类成员函数的methodID、类成员变量的fileID。之所以这么处理是避免以后每次使用Binder的时候都需要频繁的调用。