本文基于Android8.1系統進行研究
一、啟動zygote
在Linux核心啟動完成後,首先啟動系統的第一個程序init程序
init程序會讀取init.rc中的配置檔案
其中有Zygote的配置,init程序将啟動zygote程序
zygote的入口在app_main.cpp中的main函數中
二、解析傳入參數,調用AndroidRuntime的start方法
在app_main.cpp中的main函數中,首先解析傳入的相關參數,并通過如下代碼進入ZygoteInit的main函數中
Java
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
}
1
2
3
if(zygote){
runtime.start("com.android.internal.os.ZygoteInit",args,zygote);
}
runtime是AppRuntime的一個執行個體,AppRuntim繼承自AndroidRuntime
start函數定義在AndroidRuntime中,下面是start函數的注釋
1
2
3
4
5
6
7
8
9
10
11
start函數中的這段代碼切入到了startVm函數中
C++
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
1
2
3
4
5
6
7
8
JniInvocationjni_invocation;
jni_invocation.Init(NULL);
JNIEnv*env;
if(startVm(&mJavaVM,&env,zygote)!=0){
return;
}
onVmCreated(env);
三、startVm函數
這個函數前邊也是一堆處理Vm啟動參數的邏輯
在函數的最好調用JNI_CreateJavaVM函數通過c++層的庫建立虛拟機
四、JNI_CreateJavaVM函數
JNI_CreateJavaVM函數是在art/runtime/java_vm_ext.cc中實作的,代碼如下:
C++
// JNI Invocation interface.
extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
ScopedTrace trace(__FUNCTION__);
const JavaVMInitArgs* args = static_cast(vm_args);
if (JavaVMExt::IsBadJniVersion(args->version)) {
LOG(ERROR) << "Bad JNI version passed to CreateJavaVM: " << args->version;
return JNI_EVERSION;
}
RuntimeOptions options;
for (int i = 0; i < args->nOptions; ++i) {
JavaVMOption* option = &args->options[i];
options.push_back(std::make_pair(std::string(option->optionString), option->extraInfo));
}
bool ignore_unrecognized = args->ignoreUnrecognized;
if (!Runtime::Create(options, ignore_unrecognized)) {
return JNI_ERR;
}
// Initialize native loader. This step makes sure we have
// everything set up before we start using JNI.
android::InitializeNativeLoader();
Runtime* runtime = Runtime::Current();
bool started = runtime->Start();
if (!started) {
delete Thread::Current()->GetJniEnv();
delete runtime->GetJavaVM();
LOG(WARNING) << "CreateJavaVM failed";
return JNI_ERR;
}
*p_env = Thread::Current()->GetJniEnv();
*p_vm = runtime->GetJavaVM();
return JNI_OK;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// JNI Invocation interface.
extern"C"jintJNI_CreateJavaVM(JavaVM**p_vm,JNIEnv**p_env,void*vm_args){
ScopedTracetrace(__FUNCTION__);
constJavaVMInitArgs*args=static_cast(vm_args);
if(JavaVMExt::IsBadJniVersion(args->version)){
LOG(ERROR)<version;
returnJNI_EVERSION;
}
RuntimeOptionsoptions;
for(inti=0;inOptions;++i){
JavaVMOption*option=&args->options[i];
options.push_back(std::make_pair(std::string(option->optionString),option->extraInfo));
}
boolignore_unrecognized=args->ignoreUnrecognized;
if(!Runtime::Create(options,ignore_unrecognized)){
returnJNI_ERR;
}
// Initialize native loader. This step makes sure we have
// everything set up before we start using JNI.
android::InitializeNativeLoader();
Runtime*runtime=Runtime::Current();
boolstarted=runtime->Start();
if(!started){
deleteThread::Current()->GetJniEnv();
deleteruntime->GetJavaVM();
LOG(WARNING)<
returnJNI_ERR;
}
*p_env=Thread::Current()->GetJniEnv();
*p_vm=runtime->GetJavaVM();
returnJNI_OK;
}
Runtime是在art/runtime/runtime.h中定義的類
Runtime::Current()傳回一個靜态的Runtime執行個體,代碼如下:
static Runtime* instance_;
1
staticRuntime*instance_;
runtime-Start()啟動虛拟機
五、其他參考文章
Android ART運作時無縫替換Dalvik虛拟機的過程分析
Android虛拟機art流程:從zygote開始梳理art的啟動(1)
打賞
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5SYmhjMkdjY2ImM2MGOiZmY2YzNiFzM2UjYhJzN4kjNm9CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
微信掃一掃,打賞作者吧~