一、前言
准备工作
模拟器版本:MuMu模拟器(Android 6.0版本) (为什么用它?因为不用自己Root,又可以不用自己手机😀)
源码查看地址:10.0.0_r6 - Android社区 - https://www.androidos.net.cn/ (一些内核源码就可以到这里查看)
简单概括下Framework知识:
- Zygote:负责创建App进程
- ActivityManagerService(AMS):负责四大组件(Activity、Service等)的启动。
- PackageManagerService(PMS):负责给AMS提供需要的四大组件信息。
本章主要讲解Zygote的如何启动和启动后一些相关任务。
接下来,我们先看下Zygote是如何启动流程。
温馨提示:本节大部分都是一些源码流程,能梳理清流程即可。
二、Zygote如何启动
说到Zygote是如何启动的,那么就需要从Android开机说起。
Andorid开机时,会去先执行init文件,如上图文件。
温馨提示:上面的init等文件,需要手机root后才能查看,没有root条件可以下一个MuMu模拟器。
2.1 init文件
功能:init文件由下面文件编译成可执行文件init,相当于.exe可执行程序,然后会在文件执行后,去启动init.rc脚本
路径:init - Android社区 - https://www.androidos.net.cn/
2.2 init.rc
功能:存放一堆任务清单,导入了zygote脚本。
代码如下:
2.3 zygote32.rc
功能:启动 app_process,并改名为zygote
启动代码:
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
app_main.cpp - Android社区 - https://www.androidos.net.cn/
- /system/bin/app_process:程序位置,对应的代码如下
- 到此,Zygote的启动就到此为止了。
简单点概括就是:手机开机就启动Zygote,开个玩笑。
正确的流程方式:手机开机后会先去执行init文件,启动init.rc脚本,在脚本里启动了Zygote。
既然启动了Zygote,那么就继续往app_main.cpp文件里走。
三、Zygote启动流程
接下来来到app_main.cpp文件,直接看main程序执行代码:
3.1 app_main main代码
可以看到,main代码里对我们在 zygote32.rc 文件中启动 Zygote 所传入的参数进行判断。
并且zygote = true。
代码的最后,由于zygote==true,启动了ZygoteInit Java程序(注意:这个Java程序还是一个Native 进程)
并且把 zygote32.rc 所传入的参数又传给了ZygoteInit
3.2 ZygoteInit代码
在ZygoteInit的main方法中,有如下代码:
main方法里,主要梳理了两个流程。
- 预加载各种资源(例如:android.view,android.widget和一些java.io,java.lang等)
- 启动各种服务(AMS,PMS等)
接下来走一边预加载各种资源流程
3.2.1 预加载各种资源
我们知道,enableLazyPreload肯定是false,因为启动Zygote的命令里没有"--enable-lazy-preload"
就会来到下面代码,执行preLoad方法,接着往里面看
在这个方法里,会预加载很多资源,我们先从preloadClasses方法入手
通过方法的注释,我们可以知道,用来加载和初始化一些常用的类。我们看看PRELOADED_CLASSES 到底是什么
PRELOADED_CLASSES 如下:顺着下面路径往系统目录找
这就很清晰了,不都是一些我们经常用到的类嘛。包括(android.view,android.widget和一些java.io,java.lang等),接着往下看
接着就会把上面的文件,一行一行的读取,通过Class.forName加载进内存。代码如下:(注意:只会加载一份)
最后,还会去加载preloadResources(加载系统资源,也就是我们经常引用的系统样式等),preloadSharedLibraries(加载so库),preloadTextResources(字体资源),还有一些其他的预加载,可以自行看代码。
再次会到ZygoteInit的main方法中,继续往下走 启动服务流程。
3.2.2 启动服务流程
创建一个SystemServer与Zygote通信,通过Socket
通过Zygote创建SystemServer进程(Java进程)
执行SystemServer的main,执行run方法
启动服务,其中startBootstrapServices就启动了我们的AMS,PMS
创建PMS
创建AMS
到此,Zygote的介绍到此结束。留几个问题给各位思考一下:
- 问题1:Zygote为什么用Socket不用Binder?
- 问题2:每个App都会将系统的资源,系统的类都加载一遍吗?
- 问题3:init程序和init.rc的关系
- 问题3:AMS能直接调用PMS嘛?