源码位置:frameworks/base/core/jni/AndroidRuntime.cpp

头文件见:frameworks/native/libs/android_runtime_lazy/include/android_runtime/AndroidRuntime.h

start方法

其中各种关键类的定义位置:
JniInvocation:libnativehelper/JniInvocation.cpp
JNIEnv/JavaVM:libnativehelper/include_jni/jni.h,详见:http://xinyiworld.top/wordpress_it/?p=14621

//mJavaVM为全局静态变量
 309 /*static*/ JavaVM* AndroidRuntime::mJavaVM = NULL;

1128 void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
1129 {
...
1169     //const char* kernelHack = getenv("LD_ASSUME_KERNEL");
1170     //ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);
         1.第一步
1172     /* start the virtual machine */
1173     JniInvocation jni_invocation;
1174     jni_invocation.Init(NULL);
1175     JNIEnv* env;
1176     if (startVm(&mJavaVM, &env, zygote) != 0) {
1177         return;
1178     }
1179     onVmCreated(env);

         2.第二步
1181     /*
1182      * Register android functions.
1183      */
1184     if (startReg(env) < 0) {
1185         ALOGE("Unable to register all android natives\n");
1186         return;
1187     }

         2.第三步
1212     /*
1213      * Start VM.  This thread becomes the main thread of the VM, and will
1214      * not return until the VM exits.
1215      */
1216     char* slashClassName = toSlashClassName(className != NULL ? className : "");
1217     jclass startClass = env->FindClass(slashClassName);
1218     if (startClass == NULL) {
1219         ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
1220         /* keep going */
1221     } else {
1222         jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
1223             "([Ljava/lang/String;)V");
1224         if (startMeth == NULL) {
1225             ALOGE("JavaVM unable to find main() in '%s'\n", className);
1226             /* keep going */
1227         } else {
1228             env->CallStaticVoidMethod(startClass, startMeth, strArray);
1229 
1230 #if 0
1231             if (env->ExceptionCheck())
1232                 threadExitUncaughtException(env);
1233 #endif
1234         }
1235     }
1236     free(slashClassName);
1237 
1238     ALOGD("Shutting down VM\n");
1239     if (mJavaVM->DetachCurrentThread() != JNI_OK)
1240         ALOGW("Warning: unable to detach main thread\n");
1241     if (mJavaVM->DestroyJavaVM() != 0)
1242         ALOGW("Warning: VM did not shut down cleanly\n");

第一步:startVm方法 (创建Java虚拟机,解析返回JNIEnv与JavaVM)

最终会调用JNI_CreateJavaVM方法

1080     /*
1081      * Initialize the VM.
1082      *
1083      * The JavaVM* is essentially per-process, and the JNIEnv* is per-thread.
1084      * If this call succeeds, the VM is ready, and we can start issuing
1085      * JNI calls.
1086      */
1087     if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
1088         ALOGE("JNI_CreateJavaVM failed\n");
1089         return -1;
1090     }

JNI_CreateJavaVM实现位于:art/runtime/jni/java_vm_ext.cc:1188
http://xinyiworld.top/wordpress_it/?p=14042

那么最终mJavaVM变量指向JavaVMExt实例,env指向JNIEnvExt实例。

第二步:startReg方法 (注册系统类的jni方法)

https://www.jianshu.com/p/e6b9611f3045
https://blog.csdn.net/u012124438/article/details/107186262

1610 /*
1611  * Register android native functions with the VM.
1612  */
1613 /*static*/ int AndroidRuntime::startReg(JNIEnv* env)
1614 {
1615     ATRACE_NAME("RegisterAndroidNatives");
1616     /*
1617      * This hook causes all future threads created in this process to be
1618      * attached to the JavaVM.  (This needs to go away in favor of JNI
1619      * Attach calls.)
1620      */
1621     androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
1622 
1623     ALOGV("--- registering native functions ---\n");
1624 
1625     /*
1626      * Every "register" function calls one or more things that return
1627      * a local reference (e.g. FindClass).  Because we haven't really
1628      * started the VM yet, they're all getting stored in the base frame
1629      * and never released.  Use Push/Pop to manage the storage.
1630      */
1631     env->PushLocalFrame(200);
1632 
1633     if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
1634         env->PopLocalFrame(NULL);
1635         return -1;
1636     }
1637     env->PopLocalFrame(NULL);
1638 
1639     //createJavaThread("fubar", quickTest, (void*) "hello");
1640 
1641     return 0;
1642 }

→gRegJNI数组初始化:元素类型为RegJNIRec结构体,结构存储mProc的函数指针。

1400 #ifdef NDEBUG
1401     #define REG_JNI(name)      { name }
1402     struct RegJNIRec {
1403         int (*mProc)(JNIEnv*);
1404     };
1405 #else
1406     #define REG_JNI(name)      { name, #name }
1407     struct RegJNIRec {
1408         int (*mProc)(JNIEnv*);
1409         const char* mName;
1410     };
1411 #endif
1412 
1413 typedef void (*RegJAMProc)();
1414 
1415 static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)
1416 {
1417     for (size_t i = 0; i < count; i++) {
1418         if (array[i].mProc(env) < 0) {
1419 #ifndef NDEBUG
1420             ALOGD("----------!!! %s failed to load\n", array[i].mName);
1421 #endif
1422             return -1;
1423         }
1424     }
1425     return 0;
1426}
1427 
1428 static const RegJNIRec gRegJNI[] = {
1429     REG_JNI(register_android_util_SeempLog),
         ...
    }

jni注册原理示例:http://xinyiworld.top/wordpress_it/?p=14550

第三步:反射调用java类className的main方法(Android虚拟机启动第一个java类的main方法)

利用上面startVm方法得到的JNIEnv指针
对于zygote,className就是com.android.internal.os.ZygoteInit java类,源码见:http://xinyiworld.top/wordpress_it/?p=13955

分类: runtime

0 条评论

发表回复

您的电子邮箱地址不会被公开。