本章关键点总结 & 说明:java
这里关注➕Binder Java层实现中 JNI层开机初始化部分,主要谈关键类Binder、BinderInternal、BinderProxy的开机初始化流程。android
初始化Java层Binder框架(JNI的注册)架构
Java层Binder系统是在C++ 层Binder上经过JNI创建的,同时在开机时必定要在Java层Binder正式工做以前创建这种关系。这里主要分析Java层Binder框架是如何初始化。框架
在Android系统中,在Java初创时期,系统会提早注册一些JNI函数,其中有一个函数专门负责搭建Java Binder和Native Binder交互关系,该函数是register_android_os_Binder,代码以下:函数
int register_android_os_Binder(JNIEnv* env)
{
if (int_register_android_os_Binder(env) < 0) //初始化Java Binder类和Native层的关系
return -1;
if (int_register_android_os_BinderInternal(env) < 0)//初始化Java BinderInternal类和Native层的关系
return -1;
if (int_register_android_os_BinderProxy(env) < 0) //初始化Java BinderProxy类和Native层的关系
return -1;
jclass clazz;
clazz = env->FindClass("android/util/Log");
LOG_FATAL_IF(clazz == NULL, "Unable to find class android.util.Log");
gLogOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
gLogOffsets.mLogE = env->GetStaticMethodID(
clazz, "e", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I");
assert(gLogOffsets.mLogE);
clazz = env->FindClass("android/os/ParcelFileDescriptor");
LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.ParcelFileDescriptor");
gParcelFileDescriptorOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
gParcelFileDescriptorOffsets.mConstructor
= env->GetMethodID(clazz, "<init>", "(Ljava/io/FileDescriptor;)V");
clazz = env->FindClass("android/os/StrictMode");
LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.StrictMode");
gStrictModeCallbackOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
gStrictModeCallbackOffsets.mCallback = env->GetStaticMethodID(
clazz, "onBinderStrictModePolicyChange", "(I)V");
LOG_FATAL_IF(gStrictModeCallbackOffsets.mCallback == NULL,
"Unable to find strict mode callback.");
return 0;
}
据上面的代码可知,register_android_os_Binder函数完成了Java Binder架构中最重要的3个类的初始化工做。接下来继续分析注册Binder、BinderInternal、BinderProxy的过程对象
1 int_register_android_os_Binderblog
int_register_android_os_Binder函数完成了Binder类的初始化工做,代码以下:ip
static int int_register_android_os_Binder(JNIEnv* env)
{
jclass clazz;
//kBinderPathName为Java层中Binder类的全路径名,“android/os/Binder“
clazz = env->FindClass(kBinderPathName);
LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Binder");
//gBinderOffSets是一个静态类对象,它专门保存Binder类的一些在JNI层中使用的信息,
//如成员函数execTranscat的methodID,Binder类中成员mObject的fildID
gBinderOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
gBinderOffsets.mExecTransact = env->GetMethodID(clazz, "execTransact", "(IJJI)Z");
assert(gBinderOffsets.mExecTransact);
gBinderOffsets.mObject = env->GetFieldID(clazz, "mObject", "J");
assert(gBinderOffsets.mObject);
//注册Binder类中native函数的实现
return AndroidRuntime::registerNativeMethods(env, kBinderPathName,gBinderMethods, NELEM(gBinderMethods));
}
从上面代码可知,gBinderOffsets对象保存了和Binder类相关的某些在JNI层中使用的信息。ci
2 int_register_android_os_BinderInternalget
int_register_android_os_BinderInternal函数完成了BinderInternal类的初始化,代码以下:
static int int_register_android_os_BinderInternal(JNIEnv* env)
{
jclass clazz;
//kBinderInternalPathName为Java层中BinderInternal类的全路径名,“com/android/internal/os/BinderInternal”
clazz = env->FindClass(kBinderInternalPathName);
LOG_FATAL_IF(clazz == NULL, "Unable to find class com.android.internal.os.BinderInternal");
//gBinderInternalOffsets也是一个静态对象,用来保存BinderInternal类的一些信息
gBinderInternalOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
//获取forceBinderGc的methodID
gBinderInternalOffsets.mForceGc = env->GetStaticMethodID(clazz, "forceBinderGc", "()V");
assert(gBinderInternalOffsets.mForceGc);
//注册BinderInternal类中native函数的实现
return AndroidRuntime::registerNativeMethods(env, kBinderInternalPathName,
gBinderInternalMethods, NELEM(gBinderInternalMethods));
}
同上,获取一些有用的methodID和fieldID。这代表JNI层必定会向上调用Java层的函数。注册相关类中native函数的实现。
3 int_register_android_os_BinderProxy
int_register_android_os_BinderProxy完成了BinderProxy类的初始化工做,代码稍显复杂,以下所示:
static int int_register_android_os_BinderProxy(JNIEnv* env) { jclass clazz; //gErrorOffsets用来和Error类打交道 clazz = env->FindClass("java/lang/Error"); LOG_FATAL_IF(clazz == NULL, "Unable to find class java.lang.Error"); gErrorOffsets.mClass = (jclass) env->NewGlobalRef(clazz); //gBinderProxyOffsets用来和BinderProxy类打交道 clazz = env->FindClass(kBinderProxyPathName); LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.BinderProxy"); //获取BinderProxy的一些信息 gBinderProxyOffsets.mClass = (jclass) env->NewGlobalRef(clazz); gBinderProxyOffsets.mConstructor = env->GetMethodID(clazz, "<init>", "()V"); assert(gBinderProxyOffsets.mConstructor); gBinderProxyOffsets.mSendDeathNotice = env->GetStaticMethodID(clazz, "sendDeathNotice", "(Landroid/os/IBinder$DeathRecipient;)V"); assert(gBinderProxyOffsets.mSendDeathNotice); gBinderProxyOffsets.mObject = env->GetFieldID(clazz, "mObject", "J"); assert(gBinderProxyOffsets.mObject); gBinderProxyOffsets.mSelf = env->GetFieldID(clazz, "mSelf", "Ljava/lang/ref/WeakReference;"); assert(gBinderProxyOffsets.mSelf); gBinderProxyOffsets.mOrgue = env->GetFieldID(clazz, "mOrgue", "J"); assert(gBinderProxyOffsets.mOrgue); //gClassOffsets用来和Class类打交道 clazz = env->FindClass("java/lang/Class"); LOG_FATAL_IF(clazz == NULL, "Unable to find java.lang.Class"); gClassOffsets.mGetName = env->GetMethodID(clazz, "getName", "()Ljava/lang/String;"); assert(gClassOffsets.mGetName); //注册BinderProxy native函数的实现 return AndroidRuntime::registerNativeMethods(env, kBinderProxyPathName, gBinderProxyMethods, NELEM(gBinderProxyMethods)); } 至此,Java Binder几个重要成员的初始化已完成,同时在代码中定义了几个全局静态对象,分别是gBinderOffsets、gBinderInternalOffsets和gBinderProxyOffsets。框架的初始化其实就是提早获取一些JNI层的使用信息,如类成员函数的MethodID,类成员变量的fieldID等。这项工做是必需的,由于它能节省每次使用时获取这些信息的时间。当Binder调用频繁时,这些时间累积起来仍是不容小觑的。