- 通过上两个篇章,对于Binder的整体框架,以及其中驱动层的逻辑梳理之后,接下来需要对Binder的JNI层注册进行一个梳理
1. Zygote进程的启动
-
解析init.rc文件
-
Zygote是由init进程通过解析对应的init.zygote.rc文件进行创建的,这里可以看一下 init.zygote32.rc 文件
- 文件路径:android/system/core/rootdir/init.zygote32.rc
//这里会去找app_process文件夹下的app_main.cpp文件 service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server class main priority -20 user root group root readproc reserved_disk socket zygote stream 660 root system socket usap_pool_primary stream 660 root system onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse onrestart write /sys/power/state on onrestart restart audioserver onrestart restart cameraserver onrestart restart media onrestart restart netd onrestart restart wificond writepid /dev/cpuset/foreground/tasks
-
-
执行app_main.cpp文件
-
文件路径:android/frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[]) { .... AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv)); .... while (i < argc) { const char* arg = argv[i++]; if (strcmp(arg, "--zygote") == 0) { //这里会去判断当下启动的是否是zygote zygote = true; //如果是zygote,那么将zygote标志为置为true niceName = ZYGOTE_NICE_NAME; } else if (strcmp(arg, "--start-system-server") == 0) { startSystemServer = true; } else if (strcmp(arg, "--application") == 0) { application = true; } else if (strncmp(arg, "--nice-name=", 12) == 0) { niceName.setTo(arg + 12); } else if (strncmp(arg, "--", 2) != 0) { className.setTo(arg); break; } else { --i; break; } } ... if (zygote) { //这里判断如果是为zygote,那么会去启动ZygoteInit runtime.start("com.android.internal.os.ZygoteInit", args, zygote); } else if (className) { runtime.start("com.android.internal.os.RuntimeInit", args, zygote); } else { fprintf(stderr, "Error: no class name or --zygote supplied.\n"); app_usage(); LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied."); } }
在app_main.cpp中的
main()
函数中,最终调用了runtime.start()
,而runtime
就是AppRuntime
类class AppRuntime : public AndroidRuntime {}
AppRuntime
继承了AndroidRuntime
类,所以最终调用的是AndroidRuntime.start()
函数
-
2. Binder JNI的注册
-
如上面的分析,接下来会去调用
AndroidRuntime.start()
函数-
文件路径:android/framework/base/core/jni/AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote) { ..... /* * Register android functions. */ if (startReg(env) < 0) { //注册方法 ALOGE("Unable to register all android natives\n"); return; } ..... } /* * 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) { //通过此处进行系统JNI的注册 env->PopLocalFrame(NULL); return -1; } env->PopLocalFrame(NULL); //createJavaThread("fubar", quickTest, (void*) "hello"); return 0; } static const RegJNIRec gRegJNI[] = { .... REG_JNI(register_android_os_Binder), .... } 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) { //这里会循环注册所有的系统JNI,当下只关注Binder的注册 #ifndef NDEBUG ALOGD("----------!!! %s failed to load\n", array[i].mName); #endif return -1; } } return 0; }
接下来会调用到
register_android_os_Binder()
函数
-
3. register_android_os_Binder()
-
文件路径:android/framework/base/core/jni/android_util_Binder.cpp
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; jclass clazz = FindClassOrDie(env, "android/util/Log"); gLogOffsets.mClass = MakeGlobalRefOrDie(env, clazz); gLogOffsets.mLogE = GetStaticMethodIDOrDie(env, clazz, "e", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I"); clazz = FindClassOrDie(env, "android/os/ParcelFileDescriptor"); gParcelFileDescriptorOffsets.mClass = MakeGlobalRefOrDie(env, clazz); gParcelFileDescriptorOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "(Ljava/io/FileDescriptor;)V"); clazz = FindClassOrDie(env, "android/os/StrictMode"); gStrictModeCallbackOffsets.mClass = MakeGlobalRefOrDie(env, clazz); gStrictModeCallbackOffsets.mCallback = GetStaticMethodIDOrDie(env, clazz, "onBinderStrictModePolicyChange", "(I)V"); clazz = FindClassOrDie(env, "java/lang/Thread"); gThreadDispatchOffsets.mClass = MakeGlobalRefOrDie(env, clazz); gThreadDispatchOffsets.mDispatchUncaughtException = GetMethodIDOrDie(env, clazz, "dispatchUncaughtException", "(Ljava/lang/Throwable;)V"); gThreadDispatchOffsets.mCurrentThread = GetStaticMethodIDOrDie(env, clazz, "currentThread", "()Ljava/lang/Thread;"); return 0; }
int_register_android_os_Binder()
int_register_android_os_BinderInternal()
int_register_android_os_BinderProxy()
三个函数其实做的工作是一样的,都是完成java层对应Binder类的注册,从而实现JAVA层和Native层相关函数可以相互调用,下面以int_register_android_os_Binder()
函数进行示例解析:static const JNINativeMethod gBinderMethods[] = { /* name, signature, funcPtr */ // @CriticalNative { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid }, // @CriticalNative { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid }, // @CriticalNative { "isHandlingTransaction", "()Z", (void*)android_os_Binder_isHandlingTransaction }, // @CriticalNative { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity }, { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity }, // @CriticalNative { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy }, // @CriticalNative { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy }, // @CriticalNative { "setCallingWorkSourceUid", "(I)J", (void*)android_os_Binder_setCallingWorkSourceUid }, // @CriticalNative { "getCallingWorkSourceUid", "()I", (void*)android_os_Binder_getCallingWorkSourceUid }, // @CriticalNative { "clearCallingWorkSource", "()J", (void*)android_os_Binder_clearCallingWorkSource }, { "restoreCallingWorkSource", "(J)V", (void*)android_os_Binder_restoreCallingWorkSource }, { "markVintfStability", "()V", (void*)android_os_Binder_markVintfStability}, { "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 }, { "getExtension", "()Landroid/os/IBinder;", (void*)android_os_Binder_getExtension }, { "setExtension", "(Landroid/os/IBinder;)V", (void*)android_os_Binder_setExtension }, }; const char* const kBinderPathName = "android/os/Binder"; //sdk中的Binder类路径,即该cpp文件对应的是那个JAVA类 static int int_register_android_os_Binder(JNIEnv* env) { jclass clazz = FindClassOrDie(env, kBinderPathName); //下面这三步都是在将Binder.java类相关的信息记录到gBinderOffsets结构中,可以类比为反射获取类信息 //经过这一层注册,将Binder.java类信息记录在gBinderOffsets结构体中之后,就可以通过gBinderOffsets结构体,在JNI中调用Java层对应的函数 gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz); gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z"); gBinderOffsets.mGetInterfaceDescriptor = GetMethodIDOrDie(env, clazz, "getInterfaceDescriptor", "()Ljava/lang/String;"); gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J"); //入上面的gBinderMethods数组定义,此处是进行JNI层函数和java层函数的映射关联,后续想找到对应java函数的JNI层实现, //需要通过这个关系表找到java函数对应的JNI层的函数名 //经过这一层注册,就可以根据Java函数找到对应的JNI层函数 return RegisterMethodsOrDie( env, kBinderPathName, gBinderMethods, NELEM(gBinderMethods)); }