Android(安卓)P zygote 原理分析之app_process
Android系统内核初始化完毕后,进入用户空间启动的第一个进程叫init 他是Android系统所有进程的祖先,这个进程启动后会初始化文件系统,然后养育很多娃,比如系统中许许多多的服务,其中有一个服务名字就叫zygote ,zygote 翻译过来其实就叫做受精卵,它应该是init的所有娃中比较特殊的一个,其他的娃多大是一些底层服务,而zygote 这个娃的特殊之处在于它负责启动java虚拟机,并将android带入java的世界中,从此android与众不同,我想这也是android在技术上与其他众多类linux系统的主要差别之一吧!
zygote 在android中具有重要的作用,那么到底有什么用呢??
1.负责启动java虚拟机
2.加载很多需要预加载的类
3.负责启动systemServer ,systemServer 会启动android中的所有服务,基本上完成了上层框架的所有功能。
4.负责初始化新进程,其实就是fork java的独立进程,比如启动一个act,那么zygote 就负责为新启动的act 建立进程,并调用act中的main,或者OnCreate,这样或许大家更容易理解。
但是对于init来说zygote其实就是一个很普通的服务,与他养育的其他娃没有任何差别。请看代码:
service zygote /system/bin/app_process32 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote class main priority -20 user root group root readproc reserved_disk socket zygote stream 660 root system onrestart write /sys/android_power/request_state wake onrestart write /sys/power/state on onrestart restart audioserver onrestart restart cameraserver onrestart restart media onrestart restart netd onrestart restart wificond writepid /dev/cpuset/foreground/tasksservice zygote_secondary /system/bin/app_process64 -Xzygote /system/bin --zygote --socket-name=zygote_secondary class main priority -20 user root group root readproc reserved_disk socket zygote_secondary stream 660 root system onrestart restart zygote writepid /dev/cpuset/foreground/tasks
因为对于处理器平台来说有32 和64位的差别,我们手里的手机也有这个差别,所有zygote 也是有这个差别的,其实它分为32,64,32_64,64_32,这四种模式,或许有一天会有128,512模式。以上代码就是32_64位模式,主模式是32位,辅助模式是64位,其实这个手机是64位的,但是他支持32位,而这种设置会将大多数应用以32模式运行,但是一些具有特殊要求的应用也会以64位模式运行,这是负责创建进程的将是zygote_secondary。
下面我们来分析一下app_process 这个进程:
app_process 这个进程不仅能启动zygote 而且也是可以启动一个普通的类的,他会根据你参数的不同来实现不同的功能。
-Xzygote 这个参数是传给虚拟机的,并不是传给app_process 的,表示需要重新初始化一个新的jvm
--zygote: 这个参数传给app_process 表示启动zygote 模式。
--start-system-server:这个参数表示启动systemServer 服务。一般情况下,这个参数只有zygote 模式才有,因为其他模式貌似不需要这个东西。
--socket-name=zygote:这个参数表示socket 的名称,因为zygote 启动完毕后,并不会退出,他还负责为其他应用创建进程,ams就是通过这个socket与zygote 通讯来完成进程创建的。
--application:这个其实是另外一种模式的标志,表示启动的为普通应用,
--nice-name= 这个表示创建的进程的名字,zygote 模式没有这个东西。
-classpath 或者-cp 这个为创建普通应用时的class路径,我猜的。
app_process 的main函数主要是对于以上的参数的处理,除了这个之外就是新建APPRuntime类
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
这个类负责启动java的main class
if (zygote) { runtime.start("com.android.internal.os.ZygoteInit", args, zygote); } else if (className) { runtime.start("com.android.internal.os.RuntimeInit", args, zygote); } else { fprintf(stderr, "Error: no class name or --zygote supplied.\n"); app_usage(); LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied."); }
负责初始化zygote 模式的叫ZytoteInit 类,负责初始化其他进程的叫RuntimeInit 类。
其实如果要继续分析的话,则可以沿着这两条线,继续去分析,我想后面会有奇迹等着你哦!
不过我们今天的任务是分析app_process ,另外的交给未来吧!
如果要明白,app_process 如何启动jvm ,如何跳转java层,那么不分析AppRuntime 则是不现实的,估计也就变成徒有其表了。现在我们来分析今天唯一有点难度的AppRuntime
AppRuntime 继承AndroidRuntime ,因为AndroidRuntime 有两个虚函数所以,AppRuntime 主要实现这个两个函数:
/** * This gets called after the VM has been created, but before we * run any code. Override it to make any FindClass calls that need * to use CLASSPATH. */ virtual void onVmCreated(JNIEnv* env); /** * This gets called after the JavaVM has initialized. Override it * with the system's native entry point. */ virtual void onStarted() = 0; /** * This gets called after the JavaVM has initialized after a Zygote * fork. Override it to initialize threads, etc. Upon return, the * correct static main will be invoked. */ virtual void onZygoteInit() { } /** * Called when the Java application exits to perform additional cleanup actions * before the process is terminated. */ virtual void onExit(int /*code*/) { }
从名字我们就应该可以看出来,一个为虚拟机创建完毕后调用,一个为虚拟机启动完毕后调用。
对于AppRuntime 来说,onVmCreated 主要作用是设置主函数名称,onStarted函数为启动事件管理器,并且调用main函数。
对于zygote 模式来说,onVmCreated 无效。
下面我们来看看最重要的那个函数,runtime.start 函数,这个函数主要完成以下任务:
1.初始化jni
2.启动jvm虚拟机
3.注册无数的jni函数
4.启动java类
初始化jni:
主要调用jni_invocation.Init 完成初始化
if (!FindSymbol(reinterpret_cast(&JNI_GetDefaultJavaVMInitArgs_), "JNI_GetDefaultJavaVMInitArgs")) { return false; } if (!FindSymbol(reinterpret_cast(&JNI_CreateJavaVM_), "JNI_CreateJavaVM")) { return false; } if (!FindSymbol(reinterpret_cast(&JNI_GetCreatedJavaVMs_), "JNI_GetCreatedJavaVMs")) { return false; }
其实主要转换这几个jni函数,这几个jni函数会在创建虚拟机的时候被调用
创建虚拟机主要涉及无数的参数处理,最后调用JNI_CreateJavaVM 完成jvm的创建。
注册jni无数上层java需要调用的jni函数,其实这里负责调用各个jni注册函数。我猜测应该包含了系统初始化阶段所有的jni函数。
调用java类的静态main函数的方法就很通用了。貌似没什么特别的。
更多相关文章
- android 6.0 新特性
- Delphi/C++ Builder 开发 Android(安卓)程序启动画面简单完美解
- Android(安卓)MVVM:Google 为 Android(安卓)又开了一扇窗
- 探索 Android(安卓)系统启动流程 - 当我们按下电源键,Android(安
- 完全理解android事件分发机制
- Looper中的睡眠等待与唤醒机制
- Android开发之旅:环境搭建及HelloWorld (AVD无法启动,出现Starting
- 《第一行代码Android》学习总结第二章 Acitivity的生命周期与启
- Android程式编写及调试新手入门-3