android zygote启动流程,Android zygote启动流程详解
对zygote的理解
在Android系统中,zygote是一个native进程,是所有应用进程的父进程。而zygote则是Linux系统用户空间的第一个进程——init进程,通过fork的方式创建并启动的。
作用
zygote进程在启动时,会创建一个Dalvik虚拟机实例,每次孵化新的应用进程时,都会将这个Dalvik虚拟机实例复制到新的应用程序进程里面,从而使得每个应用程序进程都有一个独立的Dalvik虚拟机实例。
zygote进程的主要作用有两个:
启动SystemServer。
孵化应用进程。
启动流程
启动入口
Zygote进程在init进程中,通过解析init.zygote.rc配置文件,以service(服务)的方式启动并创建的。
以init.zygote32.rc为例来看下:
脚本讲解
// system\core\rootdir\init.zygote32.rc
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system
socket usap_pool_primary stream 660 root system
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/tasks
这段脚本要求 init 进程创建一个名为 zygote 的进程,该进程要执行的程序是“/system/bin/app_process”。并且为 zygote 进程创建一个 socket 资源 (用于进程间通信,ActivityManagerService 就是通过该 socket 请求 zygote 进程 fork 一个应用程序进程)。
后面的**--zygote**是参数,表示启动的是zygote进程。在app_process的main函数中会依据该参数决定执行ZygoteInit还是Java类。
启动过程
zygote要执行的程序便是system/bin/app_process,它的源代码在frameworks/base/cmds/app_process/app_main.cpp
App_main::main
int main(int argc, char* const argv[])
{
...
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {//是否有--zygote参数。这个是启动zygote进程的时候的参数
zygote = true;
//进程名称,设置为zygote
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) {//是否有--start-system-server
startSystemServer = true;
....
if (zygote) {
//最最重要方法。。。如果是zygote进程,则启动ZygoteInit。
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.");
}
}
AndroidRuntime::start
void AndroidRuntime::start(const char* className, const Vector& options, bool zygote)
{
...
JNIEnv* env;
//重点方法 创建VM虚拟机,参数是指针,可以用于获取返回的值,可以使用env来和Java层来做交互
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
//重点方法 给虚拟机注册一些JNI函数,(系统so库、用户自定义so库 、加载函数等。)
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
//找到类的main方法,并调用。如果是zygote的话,这里就会启动ZygoteInit类的main方法
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
//调用main方法。这里通过JNI调用Java方法之后,Zygote(Native层)就进入了Java的世界,从而开启了Android中Java的世界。
env->CallStaticVoidMethod(startClass, startMeth, strArray);
}
App_main.main
AndroidRuntime.start
startVm//创建虚拟机
startReg//注册JNI函数
ZygoteInit.main//这里就进入到了Java层了
registerZygoteSocket//建立IPC的通讯机制
preload//预加载类和资源
startSystemServer//启动system_server
runSelectLoop//等待进程创建的请求
对应的源码地址: /frameworks/base/cmds/app_process/App_main.cpp (内含AppRuntime类) /frameworks/base/core/jni/AndroidRuntime.cpp /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java /frameworks/base/core/java/com/android/internal/os/Zygote.java /frameworks/base/core/java/android/net/LocalServerSocket.java
Zygote进程的启动过程中,除了会创建一个Dalvik虚拟机实例之外,还会将Java运行时库加载到进程中,以及注册一些Android核心类的JNI方法到创建的Dalvik虚拟机实例中。
zygote进程初始化时启动虚拟,并加载一些系统资源。这样zygote fork出子进程之后,子进程也会继承能正常工作的虚拟机和各种系统资源,剩下的只需要装载APK文件的字节码就可以运行程序,。
Java应用程序不能以本地进程的形态运行,必须在一个独立的虚拟机中运行。如果每次都重新启动虚拟机,肯定就会拖慢应用程序的启动速度。
注意:APK应用程序进程被zygote进程孵化出来以后,不仅会获得Dalvik虚拟机实例拷贝,还会与Zygote一起共享Java运行时库。
以上就是Android zygote启动流程详解的详细内容,更多关于Android zygote启动流程的资料请关注其它相关文章!
android zygote启动流程,Android zygote启动流程详解相关推荐
- android应用市场点击下载APK安装详解
Android系统启动篇 1,<android系统启动流程简介> 2,<android init进程启动流程> 3,<android zygote进程启动流程> 4 ...
- [免费专栏] Android安全之数据存储与数据安全「详解」
也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 Android安全付费专栏长期更新,本篇最新内容请前往: [ ...
- Android四大组件之bindService源码实现详解
Android四大组件之bindService源码实现详解 Android四大组件源码实现详解系列博客目录: Android应用进程创建流程大揭秘 Android四大组件之bindServic ...
- Android系统性能优化(60)---LeakCanary使用详解
Android内存优化(六)LeakCanary使用详解 1.概述 如果使用MAT来分析内存问题,会有一些难度,并且效率也不是很高,对于一个内存泄漏问题,可能要进行多次排查和对比. 为了能够简单迅速 ...
- Android 事件分发机制分析及源码详解
Android 事件分发机制分析及源码详解 文章目录 Android 事件分发机制分析及源码详解 事件的定义 事件分发序列模型 分发序列 分发模型 事件分发对象及相关方法 源码分析 事件分发总结 一般 ...
- selenium工具启动Chrome浏览器时配置选项详解
mb62abf3afb54fb2022-06-18 00:02:10 文章标签chromechrome浏览器加载文章分类虚拟化云计算阅读数1473 前言 1. Chromeoptions 是Chrom ...
- android 实现毫秒定时器,Android实现定时器的五种方法实例详解
一.Timer Timer是Android直接启动定时器的类,TimerTask是一个子线程,方便处理一些比较复杂耗时的功能逻辑,经常与handler结合使用. 跟handler自身实现的定时器相比, ...
- android listview ontouchlistener,Android ListView监听滑动事件的方法(详解)
ListView的主要有两种滑动事件监听方法,OnTouchListener和OnScrollListener 1.OnTouchListener OnTouchListener方法来自View中的监 ...
- android edittext 过滤英文名称,Android 限制edittext 整数和小数位数 过滤器(详解)
写了一个过滤器,根据需要限制edittext输入的整数和小数位,如下代码: package allone.verbank.apad.client.component; import android.t ...
- android平台下OpenGL ES 3.0实例详解顶点属性、顶点数组
OpenGL ES 3.0学习实践 android平台下OpenGL ES 3.0从零开始 android平台下OpenGL ES 3.0绘制纯色背景 android平台下OpenGL ES 3.0绘 ...
最新文章
- Ubuntu画图工具
- 鸿蒙内核源码分析:调度机制篇
- QQ音乐的各种相关API
- matlab显示像素分布,MATLAb-----7--------如何动态显示鼠标的坐标值和图像像素值
- Java中常见的日志框架
- 返回一个1到54之间的随机数
- linux红帽6架设apache,linux Redhat6.5 中 编译安装apache
- Redis+Twemproxy安装与使用
- 记一次CurrentDirectory导致的问题
- java复习web篇——servlet
- Java web(2012/2/22)
- EL表达式用法---查询博客
- 【大数据24小时】“天智一号”卫星将在太空计算数据;“电子身份证”亮相支付宝...
- Microsoft JET Database Engine (0x80004005)操作必须使用一个可更新的查询
- 什么索引?索引的作用是什么?索引运用实例
- 调用百度翻译api实现中英文翻译
- 嵌入式系统开发-麦子学院(11)——ARM Cortex A8 硬件基础(1)
- CERC2017 F-Faulty Factorial【数论】
- Spring Security认证_内存认证
- 那些年面挂的js手写题