android源码分析之Runtime的初始化Word文件下载.docx
- 文档编号:20171436
- 上传时间:2023-01-17
- 格式:DOCX
- 页数:17
- 大小:458.32KB
android源码分析之Runtime的初始化Word文件下载.docx
《android源码分析之Runtime的初始化Word文件下载.docx》由会员分享,可在线阅读,更多相关《android源码分析之Runtime的初始化Word文件下载.docx(17页珍藏版)》请在冰豆网上搜索。
mode=0755"
);
mkdir("
/dev/pts"
0755);
/dev/socket"
devpts"
0,NULL);
proc"
/proc"
sysfs"
/sys"
}
open_devull_stdio();
//klog初始化
klog_init();
klog_set_level(KLOG_NOTICE_LEVEL);
if(!
is_first_stage){
//关闭/dev/.booting文件的相关权限
close("
/dev/.booting"
O_WRONLY|O_WCREAT|O_CLOEXEC,000);
//初始化部分属性
property_init();
//先初始化DT,因为DT的属性集的优先级高于comandline
process_kernel_dt();
//处理内核命令行
process_kernel_cmdline;
//导出内核变量
export_kernel_boot_props();
//初始化信号量
signal_handler_init();
property_load_boot_defaults();
//开启属性服务
start_property_service();
//解析/init.rc文件
init_parse_config_file(/init.rc);
此处的代码与android4.4等,在代码上有略微的差别,但是基本的操作还是一样的,首先进行一些属性的初始化,内核命令行等以及信号量的初始化,最后再启动属性服务以及对init.rc文件进行解析,所以,接下来分析Init.rc文件:
//Init.rc
import/init.environ.rc
import/init.usb.rc
import/init.${ro.hardware}.rc
import/init.${ro.zygote}.rc
import/init.trace.rc
...
由代码可知,与android4.4等有明显的差别,此处采用导入.rc文件的方式来初始化相应模块,此处分析zygote模块,对于android6.0来说,它提供了多个zygote相关的.rc文件,有Init.zygote32.rc、Init.zygote32_64.rc、Init.zygote64.rc、Init.zygote64_32.rc等,本文分析Init.zygote32.rc,其他流程是一样的,但是在源码中,只发现了Init.zygote32.rc的相关实现。
看Init.zygote32.rc文件:
//Init.zygote32.rc
servicezygote/system/bin/app_process-Xzygote/system/bin--zygote--start-system-server
classmain
socketzygotestream660rootsystem
onrestartwrite/sys/android_power/request_statewake
onrestartwrite/sys/power/stateon
onrestartrestartmedia
onrestartrestartnetd
由代码可知,它将会执行/system/bin/app_process,而后面的是它的参数,请注意–zygote和–start-system-server参数,后面将会分析到,而对于/system/bin/app_process的实现app_main.cpp(frameworks/base/cmds/app_process),它的配置在frameworks/base/cmds/app_process目录下的Android.mk文件中:
//Android.mk(frameworks/base/cmds/app_process)
LOCAL_PATH=$(callmy-dir)
app_process_common-shared_libs:
=\
libwilhelm\
include$(CLEAR_VARS)
#看,app_process命令绑定的源码就是该目录下的app_main.cpp
LOCAL_SRC_FILES:
app_main.cpp
所以,app_process命令绑定的源码实现就是app_main.cpp,在解析Init.zygote32.rc文件的时候,会调用到它的main函数,即app_main.cpp的main函数。
3、Android运行时的启动分析
上一节分析了Init进程启动与android运行时的关系,因为对于android运行时的启动来说,它是在Init进程之后,zygote进程启动之后,初始化之前初始化的,所以此时它的入口和zygote的入口一致,即app_main.cpp的main函数,代码如下:
//app_main.cpp
intmain(intargc,char*constargv[]){
//AppRuntime继承自AndroidRuntime
AppRuntimeruntime(argv[0],computeArgBlockSize(argc,argv));
if(zygote){//如果init.rc配置中有--Zygote,参数为com.android.internal.os.ZygoteInit
runtime.start("
com.android.internal.os.ZygoteInit"
args);
}elseif(className){//否则参数为com.android.internal.os.RuntimeInit
com.android.internal.os.RuntimeInit"
}else{
//显示命令的用法说明
app_usage();
}
首先创建一个AppRuntime对象,接着调用它的start方法,而此start方法在父类AndroidRuntime中进行了定义,并且此处的参数为com.android.internal.os.ZygoteInit,而对于两种不同的参数而言,只是最后启动的类不一样,如果有–zygote参数,其最后会启动ZygoteInit类,否则就会执行RuntimeInit类,继续追踪start方法。
//AndroidRuntime.cpp
voidAndroidRuntime:
:
start(constchar*className,constVector<
String8>
&
options){
//启动虚拟机
if(startVm(&
mJavaVM,&
env)!
=0){
return;
//模板方法模式,只是为了创建VM之后释放slashClassName的内存
onVmCreated(env);
//注册AndroidJNI函数
if(startReg(env)<
0){
ALOGE("
Unabletoregisterallandroidnatives\n"
//解析类名
char*slashClassName=toSlashClassName(className);
//找到需要启动的java类
jclassstartClass=env->
FindClass(slashClassName);
if(startClass==NULL){
JavaVMunabletolocateclass'
%s'
\n"
slashClassName);
}else{
//得到指定类中指定方法的ID,这里得到的是RuntimeInit.main()的方法ID
jmethodIDstartMeth=env->
GetStaticMethodID(startClass,"
main"
"
([Ljava/lang/String;
)V"
if(startMeth==NULL){
JavaVMunabletofindmain()in'
className);
//调用上面得到的方法ID和相关参数,即调用Java类ZygoteInit.main();
env->
CallStaticVoidMethod(startClass,startMeth,strArray);
首先分析Java虚拟机的启动:
由以上代码可知,在start方法中,调用startVm()方法进行虚拟机的启动,startVm()的具体代码如下:
intAndroidRuntime:
startVm(JavaVM**pJavaVM,JNIEnv**pEnv,boolzygote){
//读取第一个参数指定的属性操作到buffer,并设置默认的参数
parseRuntimeOption("
dalvik.vm.stack-trace-file"
stackTraceFileBuf,
-Xstacktracefile:
"
//添加相应的handler操作
addOption("
exit"
(void*)runtime_exit);
//读取作为dex2oatcompiler运行时操作
parseCompilerOption(dex2oat_isa_variant_key,dex2oat_isa_variant,
--instruction-set-variant="
"
-Xcompiler-option"
//拷贝特性
sprintf(dex2oat_isa_features_key,"
dalvik.vm.isa.%s.features"
instruction_set);
parseCompilerOption(dex2oat_isa_features_key,dex2oat_isa_features,
--instruction-set-features="
-Ximage-compiler-option"
//初始化虚拟机
if(JNI_CreateJavaVM(pJavaVM,pEnv,&
initArgs)<
JNI_CreateJavaVMfailed\n"
return-1;
由代码可知:
首先进行一系列的属性读取到buffer的操作,如JIT相关的options,DexClassLoader的相关options等,并将其添加到操作数组容器里面,最后再调用JNI_CreateJavaVM方法进行VM的创建,如果此调用发挥成功的话,那么我们就能够济宁JNI调用了,继续看此方法的代码,它的定义出现在DdmConnection的start方法里:
//DdmConnection.cpp
voidDdmConnection:
start(constchar*name){
//定义JNI_CreateJavaVM方法
jint(*JNI_CreateJavaVM)(JavaVM**p_vm,JNIEnv**p_env,void*vm_args);
//从libart_dso库中解析JNI_CreateJavaVM方法
JNI_CreateJavaVM=reinterpret_cast<
decltype(JNI_CreateJavaVM)>
(
dlsym(libart_dso,"
JNI_CreateJavaVM"
));
//定义registerNatives方法
jint(*registerNatives)(JNIEnv*env,jclassclazz);
//从libandroid_runtime_dso库中解析registerNatives方法
registerNatives=reinterpret_cast<
decltype(registerNatives)>
dlsym(libandroid_runtime_dso,
Java_com_android_internal_util_WithFramework_registerNatives"
JNI_CreateJavaVM方法是从libart_dso库中解析得到的,同样后面要用到的registerNatives方法从事libandroid_runtime_dso库中解析得到的,而这两个库也是在DdmConnection的start方法中打开的,代码如下:
void*libart_dso=dlopen("
libart.so"
RTLD_NOW);
ALOGE_IF(!
libart_dso,"
DdmConnection:
%s"
dlerror());
void*libandroid_runtime_dso=dlopen("
libandroid_runtime.so"
libandroid_runtime_dso,"
而当JNI_CreateJavaVM函数执行成功后,当前本地线程已经把自己的控制权交给JVM,而具体的JNI_CreateJavaVM方法的实现在libart_dso库中,此处不做深究。
至此,成功创建了Java虚拟机,而startVm方法也分析结束。
接着分析onVmCreated方法,它使用的是模板方法的设计模式,在androidRuntime中声明并使用,而具体的实现在appRuntime子类中进行,其代码如下:
virtualvoidonVmCreated(JNIEnv*env){
if(mClassName.isEmpty()){
//Zygote.Nothingtodohere
char*slashClassName=toSlashClassName(mClassName.string());
mClass=env->
FndClass(slashClassName);
if(mClass==NULL){
ERROR:
couldnotfindclass'
mClassName.string);
free(slashClassName);
mClass=reinterpret<
jclass>
(env->
NewGlobalRef(mClass));
只是简单根据类名获取了类,并释放了类名,所以此处不做过多的分析,接下来分析startReg()方法,方法定义代码如下:
/*static*/intAndroidRuntime:
startReg(JNIEnv*env)
/*
*Thishookcausesallfuturethreadscreatedinthisprocesstobe
*attachedtotheJavaVM.(ThisneedstogoawayinfavorofJNI
*Attachs.)
*/
androidSetCreateThreadFunc((android_create_thread_fn)javaCreateThreadEtc);
ALOGV("
---registeringnativefunctions---\n"
*Every"
register"
functioncallsoneormorethingsthatreturn
*alocalreference(e.g.FindClass).Becausewehaven'
treally
*startedtheVMyet,they'
reallgstoredinthebaseframe
*andneverreleased.UsePush/Poptomanagethestorage.
PushLocalFrame(200);
if(register_jni_procs(gRegJNI,NELEM(gRegJNI),env)<
PopLocalFrame(NULL);
startReg方法主要的作用是进行androidJNI函数的注册,从代码可知:
它调用函数register_jni_procs()方法将gRegJNI中的方法注册到虚拟机,而gRegJNI中的Native方法如下:
staticconstRegJNIRecgRegJNI[]={
REG_JNI(register_com_android_internal_os_RuntimeInit),
REG_JNI(register_android_os_SystemClock),
REG_JNI(register_android_util_EventLog),
REG_JNI(register_android_util_Log),
REG_JNI(register_android_content_AssetManager),
REG_JNI(register_android_content_StringBlock),
REG_JNI(register_android_content_XmlBlock),
REG_JNI(register_android_emoji_EmojiFactory),
REG_JNI(register_android_text_AndroidCharacter),
REG_JNI(register_android_text_StaticLayout),
REG_JNI(register_android_text_AndroidBidi),
REG_JNI(register_android_view_InputDevice),
REG_JNI(register_android_view_KeyCharacterMap),
REG_JNI(register_android_os_Process),
REG_JNI(register_android_os_SystemProperties),
REG_JNI(register_android_os_Binder),
REG_JNI(register_android_os_Parcel),
REG_JNI(register_android_nio_utils),
REG_JNI(register_android_graphics_Graphics),
REG_JNI(register_android_view_DisplayEventReceiver),
REG_JNI(register_android_view_RenderNode),
REG_JNI(register_android_view_RenderNodeAnimator),
REG_JNI(register_android_view_GraphicBuffer),
REG_JNI(register_android_view_DisplayListCanvas),
REG_JNI(register_android_view_HardwareLayer),
REG_JNI(register_android_view_ThreadedRenderer),
REG_JNI(register_android_view_Surface),
REG_JNI(register_a
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- android 源码 分析 Runtime 初始化
![提示](https://static.bdocx.com/images/bang_tan.gif)