系统启动流程
首先是这个Loader层,当手机处于关机状态时,我们长按电源键它就会开机。主板通电之后,会引导芯片开始执行烧录在存储器里的预设代码,然后加载引导程序到我们的内存中。这里主要是做一些内存检查和硬件参数的初始化等功能。
开机引导程序执行完成之后,就会开始加载Linux Kernel的核心代码。在这一层里面,主要是去加载一些硬件的驱动,比如我们常用的相机驱动、显示屏驱动、输入驱动,还有一些media服务等驱动。硬件的驱动是在Kernel这一层所加载的。但是如果说我们的上层应用想要访问这个硬件设备的话,都必须要通过这个Hardware Abstract Layer,也就是我们通常所说的硬件抽象层。硬件抽象层的设计主要是为了解决各家驱动提供商所提供的驱动标准不统一的问题。这些问题都由硬件抽象层来适配,为上层应用提供统一的API。
硬件驱动加载完成之后,可以创建Linux中的第一个用户进程,也就是Init
进程(pid=1)。它会孵化出adbd进程以及logd进程。这就是我们为什么可以运行时断点调试和输出日志的原因。就是因为这两个守护进程的存在,Init进程执行完成之后,它还会孵化出第一个java进程,也就是Zygote进程。Zygote进程是由init进程解析init.rc脚本创建的
Zygote进程,它是一个承上启下连接java世界和native之间的一个存在。Zygote进程创建成功之后,就会进入到了我们的java层。它会调用ZygoteInit.java
这个类,创建安卓framework系统服务SystemServer进程。后续我们所有APP的进程都是由Zygote这个进程孵化而来的。APP进程创建完成之后,都会由ZygoteInit反射调用APP进程的入口类ActivityThread,从而启动APP。
ZygoteInit.main()
在ZygoteInit这个类的入口方法main方法里面,实际上还启动了SystemServer,也就是系统服务进程。这个进程创建成功之后,也会执行它的入口类,也就是SystemServer.java这个类的入口方法里面,又会去创建许多我们熟知的系统服务。比如说ActivityManagerService、WindowManagerService、PowerManagerService以及InputManagerService。等所有的系统服务都创建成功之后,就开始执行Launcher这个启动流程了。
scss
复制代码
//ZygoteInit.java
public static void main(String argv[]){
//1,预加载frameworks/base/preloaded-classes和framework_res,apk资源
preloadClasses();
preloadResources();
preloadSharedLibraries();
// 2.启动system_server进程。该进程是framework的核心。
if(argv[1].equals("start-system-server")){
startSystemServer();
}
//3.创建Socket服务
registerZygoteSocket();
//4.进入阻塞状态,等待连接,用以处理来自AMS申请进程创建的请求
runSelectLoopMode();
}
在ZygoteInit这个类的main方法里面,它主要做了以下四件事情。
第一个就是资源的预加载,加载系统的class文件,加载系统的资源文件,加载系统的动态库。因为我们所开发的上层应用在运行的时候会使用到大量的系统资源。而如果这些系统资源在APP启动的时候再去加载的话,那这势必会造成APP启动缓慢。而如果在系统启动的时候就把这些资源文件提前预加载,就可以达到提高APP启动速度的目的。APP在运行时,也能够去共享使用这些资源文件。
第二个功能是通过main方法里面传入的argv这个数组,去判断是否有包含"start-system-server"这个参数,以决定要不要启动SystemServer进程。这个进程是android framework的核心进程,很多service都是运行在这个进程里面的。
第三,创建了一个Socket服务。这个Socket的服务是用来接受来自ActivityManagerService申请进程创建的请求的。
Socket服务创建完成之后,就会进入一个阻塞状态,等待客户端的连接。
SystemServer.main()
/frameworks/base/services/java/com/android/server/SystemServer.java
scss
复制代码
public static void main(String argv[]){
//创建系统的服务的管理者
SystemServiceManager mSystemServiceManager = new SystemServiceManager(mSystemContext);
//启动引导服务
startBootstrapServices();
//启动核心
startCoreServices();
//启动其他一般服务
startOtherServices();
}
SystemServer进程创建成功之后,也会进入它的一个入口类。它的入口类叫SystemServer.java
在它的入口方法里面启动了非常多的系统服务。这些系统服务都交由SystemServiceManager来管理。这些系统服务大致上可以分为三类,引导服务以及核心服务和其他一般服务。这些具体的服务用下面示意图来表示。
在SystemServer这个进程当中,大大小小前前后后一共会启动110多个启动服务。这些系统服务构成了安卓的framework层,为我们的日常APP开发和运行提供了保障。
当所有的系统服务都启动完成之后,在startOtherServices这个方法的最后有这样一行代码
ini
复制代码
mActivityManagerService.systemReady(() -> {
...
});
目的是通知ActivieManager去启动第三方应用。所以到这里,所有的系统服务启动完成之后,就开始通知ActivityManagerService调用它的systemReady去启动Launcher应用了。
总结
Android 系统的启动流程可以分为以下几个步骤:
- 通电启动:按下电源按钮时,硬件会开始引导启动过程。
- 引导加载程序(Bootloader):在加电启动后,引导加载程序(Bootloader)会运行,它是设备的第一个启动软件,负责初始化硬件环境、加载并启动操作系统内核。
- Linux 内核启动:引导加载程序会加载 Linux 内核并启动它。
- init 进程启动:Linux 内核启动后,会执行用户空间的第一个进程 init,它是 Android 系统的初始化进程。主要做了系统资源的预加载,以提高APP启动的响应速度。
- Zygote 进程启动:在 init 进程中,会启动 Zygote 进程,它是 Android 系统中应用程序进程的孵化工厂。
- SystemServer 进程启动:Zygote 进程在启动后,会创建另一个重要的进程SystemServer进程。SystemServer 是 Android 系统的核心服务进程,负责管理和运行系统级服务,如 ActivityManagerService、PackageManagerService、WindowManagerService 等。
- 启动Launcher:到这里就看到了桌面UI了。