【分析】dalvik虚拟机启动过程(三)

时间:2022-02-21 09:53:34

源码版本:Android-4.4.4_r2

提示:大部分分析直接注释在代码内。

相关文章:

【分析】dalvik虚拟机启动过程(一)

【分析】dalvik虚拟机启动过程(二)


AndroidRuntime::start中调用AndroidRuntime::startVm函数启动了虚拟机,然后又调用了AndroidRuntime::startReg函数注册Android函数:

/*
* 向 VM 注册Android本地函数。
* Register android native functions with the VM.
*/
/*static*/ int AndroidRuntime::startReg(JNIEnv* env)
{
// 这个函数还不知道是干嘛的!
/*
* 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);

// gRegJNI是一个函数列表,这些函数会注册一些本地函数。
if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
env->PopLocalFrame(NULL);
return -1;
}
env->PopLocalFrame(NULL);

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

return 0;
}

gRegJNI:

static const RegJNIRec gRegJNI[] = {
......
REG_JNI(register_android_util_Log),
......
};

REG_JNI(register_android_util_Log) 来说,函数 register_jni_procs 会调用 register_android_util_Log

/*
* JNI registration.
*/
static JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
{ "isLoggable", "(Ljava/lang/String;I)Z", (void*) android_util_Log_isLoggable },
{ "println_native", "(IILjava/lang/String;Ljava/lang/String;)I", (void*) android_util_Log_println_native },
};
int register_android_util_Log(JNIEnv* env)
{
jclass clazz = env->FindClass("android/util/Log");

if (clazz == NULL) {
ALOGE("Can't find android/util/Log");
return -1;
}

levels.verbose = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "VERBOSE", "I"));
levels.debug = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "DEBUG", "I"));
levels.info = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "INFO", "I"));
levels.warn = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "WARN", "I"));
levels.error = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "ERROR", "I"));
levels.assert = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "ASSERT", "I"));

return AndroidRuntime::registerNativeMethods(env, "android/util/Log", gMethods, NELEM(gMethods));
}

register_android_util_Log函数向 java.util.Log 类中注册了 gMethods 中的两个方法:isLoggable和println_native。 
但是当我打开eclipse时,查看Log类中的源码并没有这两个类,我又用了jd-jui打开了Android SDK中4.4的jar包,发现了native方法isLoggable,但是依旧没有发现println_native方法,我猜测Android SDK中的类和方法毕竟是 不全的


结语:还有很多地方没有分析到,比如dalvik虚拟机参数的分析、dvmStartup函数中大量初始化函数的功能等。