Android系统启动流程

在这里插入图片描述

1.手机通电

首先,手机通上电,手机设备会在BootLoader分区进行一些硬件的初始化,硬件的一些自检,类似pc电脑的bios自检。

2.BootLoader分区

自检成功了,硬件输入没有问题了,你的输入输出系统没有问题了, 你会接收用户的按键。你会接收一些组合按键,不同的组合按键会进入不同的模式。

3.进入不同模式

BootLoader模式

这个模式下可以进行线刷,通过镜像包可以直接烧写分区,通过fastboot这种工具。

recovery分区

这种模式进行系统的更新,用户数据的擦写,他会把recovery这个分区加载进来,recovery也是一个小型的Linux操作系统,他里面包含Linux内核,内核加载成功以后他会有一个init程序,init程序就是Linux系统的第一个用户进程。init也会去读取一个叫init.rc的配置文件。
这个我们要看一下源码了,recovery分区里面的init程序,他所读的init.rc
在这里插入图片描述

他也会去挂载一些分区,有一个分区系统,因为你要操作那些分区,进行镜像烧写,首先要知道那些分区在哪。
在这里插入图片描述

还有,他会去启动一个recovery程序。这也是个二进制程序,把她启动起来我们才叫进入了recovery模式。
在这里插入图片描述

在recovery模式我们可以进行系统更新和用户数据擦除。recovery也是定制的,有些公司也会把recovery做得非常炫。

recovery模式也可以重启,又走一遍操作,什么都不做,什么按键都没去按,就会通过正常模式加载进入到boot分区。

正常模式(boot分区)

boot分区跟recovery分区差不多,也有一个Linux内核,也有一个init程序,他这里就不是启动recovery程序进入recovery模式了,他这里启动的是zygote程序进入到android系统当中,这个init程序也去读一个init.rc,这个inint.rc是一个初始化配置文件。
在这里插入图片描述

4.init程序做了什么?

1.读取init.rc并执行
2.根据fstab分区表挂载分区
3.启动Zygote等/system/bin/app_process…

zygote在什么时候启动起来呢?
zygote启动起来之前我们还要说一下这个分区的问题,分区会通过一个分区表去挂载,我们可以去看一下,这边有一些很复杂的操作,但是我们只找关键字,不去纠结他们都是干嘛的。
首先文件系统他会去读取一个分区表,分区表叫fstab,fstab也是一个文件,这个文件我们也可以看一下。android源码当中,找一个文件
在这里插入图片描述

他列出来很多,很多都是在device下,device是设备,像华为(huawei),华硕(asus),LG(lge),每一个设备有每一个设置的分区表。这些是厂商进行定制的,这一般都是硬件工程师把这些定出来,分区表里面会去定义怎么去挂载system分区,cache分区。我们通过华为的看一眼。
在这里插入图片描述

左边是block,右边是目录,还有就是格式和分区的配置。目录对应的就是分区表。
在这里插入图片描述

分区表挂载成功就进入zygote的启动。

zygote是在哪启动的呢?
以前zygote就是直接在init.rc里面,现在把她导到另外一个配置文件里面了,因为现在很多设备也分cpu64位的,32位的,所以就不能单纯启动某一种zygote。
在这里插入图片描述

他会根据根据你当前的配置分四种。
在这里插入图片描述

我们就看32位的。32位的就是启动的bin下的app_process这个程序。
在这里插入图片描述

也就是我们init程序启动起来以后,看一下模拟器
切换到系统目录下
在这里插入图片描述

ps显示所有进程
在这里插入图片描述

init程序启动起来以后,他会去启动zygote,zygote调用的是system目录下bin/app_process
在这里插入图片描述

我们看到process有32位的和普通的app_process。
就是这个bin,init会去调用这个bin,调用app_process这个程序,然后后边还会跟一些参数。这个参数是后续一些逻辑需要用到的参数。那这个参数是在哪定义的呢?我们回到这个里边。
在这里插入图片描述

zygote里面有个–zygote,然后是–start-system-server,我们记住这两个参数,这两个参数就是app_process这个程序后面跟的参数。他是怎么使用者两个参数的呢?
app_process对应的源码是app_main.cpp,c语言也是看程序入口,main函数
在这里插入图片描述

5.Zygote进程:App_main_cpp.main()

main函数里边,首先做了几件事情,
1.解析app_process的参数,参数就是–zygote,–start-system-server
2.解析完参数,设置当前进程为zygote进程,通过设置进程名
3.然后调用AndroidRuntime.start

我们把这每一步对应源码去找一下
首先解析参数
在这里插入图片描述

这里边有一个while循环,循环里面好像在解析上面参数,–zygote通过strcmp对比,有没有这个参数,有的话,zygote = true,nicename = …,nicename其实就是我们的进程名字。
在这里插入图片描述

下面就是解析–start-system-server,解析完就把startSystemServer变为true
zygote和startSystemServer好像是两个比较重要的参数,那我们看他在哪用了。
在这里插入图片描述

把startSystemServer对象放到了args对象里面,args看起来跟集合似的
在这里插入图片描述

在做if(zygote)操作之前,设置进程名称为zygote
在这里插入图片描述

对应到真实设备里边就是zygote进程。
在这里插入图片描述

走完这一步,他开始调用AndroidRuntime.start,又跳到另外一个类当中。
在这里插入图片描述

第一个参数看起来像一个包名,看起来像一个java的文件,args是刚刚的集合,zygote就是true。

我们跳到AndoridRuntime.cpp的start方法
在这里插入图片描述

6.AndroidRuntime.cpp.start()

首先看一下AndroidRuntime.cpp.start()他做了些什么:
1.启动虚拟机startVm:因为后边要去加载java的类,虚拟机首先要启起来
2.注册JNI方法startReg:因为虚拟机里面要涉及到一些native的方法,首先要把JNI的环境搭建起来。
3.反射调用ZygoteInit.main:最后又跳出去了,最后又回到了ZygoteInit.main里边

先看看虚拟机怎么启起来的
在这里插入图片描述

startVm返回不等于0就是启动失败,直接退出,成功后startReg,注册JNI环境。
然后下面就是反射调用传过来的ZygoteInit的main函数。
在这里插入图片描述

然后进入到ZygoteInit当中

到这就是java代码了。

7.ZygoteInit.java.main()

ZygoteInit.java.main()又做了哪些事情呢?
1.启动预加载preload()
2.startSystemServer会fork并配置子进程system_server:之前都是在zygote进程里面,这里把system_server进程弄出来了。
3.通过RuntimeInit反射调用启动SystemServer.main

首先预加载,加载了什么?
在这里插入图片描述

预加载类,预加载资源,预加载openGl,预加载共享库,预加载文字资源,与加载webview。
安卓系统在启动过程中,可以多做一些工作,后续应用调用资源的时候就不用去加载字节码了,他可以直接用了,这些预加载就是在zygoteinit的时候加载进来的。
如果公司做一些系统启动的优化,让系统启动快一些,后续应用启动可以慢一些,那就可以在这里做工作。

再看startSystemServer,zygote通过fork又创建了一个进程system_server,他把system_server启动起来放到这个子进程里面。
在这里插入图片描述

8.来到SystemServer.java.main()

先看他做了什么
1.初始化Looper:Looper.prepareMainLooper()
2.加载服务的JNI库:System.loadLibrary(“android_servers”)
3.创建SystemServiceManager
4.启动Android服务
startBootstartServices
startCoreServices
startOtherServices(会执行ActivityManagerService.systemReady)
在这里插入图片描述

跳到run,进行一些设置以后,从这一步正式进入安卓系统服务。
在这里插入图片描述

到这一步,这个方法大家很熟悉,初始化一个MainLooper
在这里插入图片描述

只要跟android相关了,handler这个机制就不可避免要用到,handler你要去发送一些延时消息,你系统需要不断地去监测别人给你发过来的一些请求,SystemServer很忙的,SystemServer需要一直等在这。不断地等待其他的应用,api去访问一些请求,请求了我就处理。所有应用调用api的时候到要找到他,他是系统服务嘛,他是安卓系统framework层的基石,首先要有一个MainLooper不断地在这里loop。
在这里插入图片描述

他是systemserver的这个进程的主线程的mainlooper,先初始化出来。然后去加载安卓server的so库。这个也是需要调用他的jni的。我们普通应用调用的时候有jni,我们系统服务server调用的时候也有一些jni,他有些东西不可能自己完全用java代码实现。他需要本地代码去实现。
在这里插入图片描述

这个就是android_servers这个so。加载的时候不需要加libandroid和so,他是一种命名规范,他会自动去找。
在这里插入图片描述

然后初始化系统的context,创建一个系统服务的管理器。系统有非常多的服务,他需要有一个管理者,管理进行查找。
在这里插入图片描述

管理者先初始化出来,然后start services
在这里插入图片描述

简简单单三个方法,每个方法都对服务进行了分类。
Bootstrap里面就有:activitymanagerService、powermanagerService、LightService…
Core:核心的services,电源电池…
Other:很多android调用的service都在这里实现,WindowmanagerService、inputmanagerservice…

9.ActivityManagerService.java.systemReady()

一直到我们关注的出口ActivityManagerService.java.systemReady()
每个服务都会systemReady(),我们找的就是最后一个systemReady(),这是一个出口
在这里插入图片描述

出到哪了呢?我们找到ActivityManagerServer中systemReady()的实现
在这里插入图片描述

我们先看一下systemReady()里面做了些什么,再去找,加深印象
1.系统准备工作systemReady(),后续启动应用的准备工作
2.发送开机广播finishBooting(),关键性操作,开机广播是在ActivityManagerService.java.systemReady()发送的
3.启动桌面应用startHomeActivityLocked()

我们先去找找系统准备工作,准备工作有很多,前面可以说都是一些准备工作,一直到
在这里插入图片描述

准备工作完了,我们去找开机广播的操作。
在这里插入图片描述

启动初始化的activity,下面一行是启动桌面应用,发送开机广播是通过finishBooting(),我们找一下这个方法,到这里的时候mBooting为true
在这里插入图片描述

他会初始化一个intent,然后发送开机广播。
开机广播做完以后就是startHomeActivityLocked(),startHomeActivityLocked()这个里面还有非常复杂的逻辑,我们只要知道他调完startHomeActivityLocked()以后,会把launcher启起来。他肯定会去遍历当期安装的apk里面哪些是桌面属性的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值