源码位置: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
0 条评论