android-10源码分析App启动流程(⼀)
制作android软件流程(⼀)在系统的app启动前
1.机器Poweron(芯⽚烧录的时候已经设置好的,会根据硬件以及GPU的设置来判断系统启动是在U盘还是sdcard或者内置flash中,去引导uboot)
2.bootloader(它是嵌⼊式系统上电后加载的第⼀段代码,这段代码的主要作⽤是进⾏硬件初始化,获取内存⼤⼩信息等,调整⼿机到适配状态,在它完成CPU和相关硬件的初始化之后,再将操作系统映像或固化的嵌⼊式应⽤程序装在到内存中然后跳转到操作系统所在的空间,启动操作系统运⾏)
具体BootLoader的主要类型与⽀持的系统类型参考:
具体的BootLoader的功能参考:
根据参考⽬前通⽤的BootLoader的类型是U-boot
3.uboot(初始化外设⽐如内存flash以及cpuI/O,并且通过串⼝修改启动参数的配置过程,根据配置的参数引导内核即kernel)
启动模式包括两种:
1)升级模式
recovery升级模式,启动recovery分区中的内核&⽂件系统
2)正常启动模式
引导正常内核和安卓⽂件系统
Uboot如何区分这两种模式:
⽅式⼀:设备上电,设备启⽤到Uboot模式,会进⼊且触发输⼊模式并输⼊recovery命令,重启uboot的时候就会检查到这个命令,uboot 会直接去引导recovery分区
从⽽进⼊recovery模式;
⽅式⼆:如果没有设置recovery命令,uboot启动过程中也会等待按键输⼊(例如power + volume up/down),在等待按键输⼊的这段时间捕获到了组合按键,uboot也会直接引导recovery分区
⽅式三:系统正常启动后下载安装包调⽤reboot命令进⾏recovery升级,重启后直接进⼊recovery模式
如果上诉三种⽅式都不满⾜那uboot会直接进⼊boot模式,正常启动设备
recovery模式会完成系统升级和部分数据清除
系统升级分为两种模式:差量包升级(只升级部分内容容量⼩) & 全包升级
recovery包与正常的⽂件系统是有分别的,特点是⽐较⼩,不⽤启动很多服务,使⽤过程中会将system分区挂载起来,将设备的system ⽂件与差两百中的
⽂件进⾏⽐对,将不⼀样的地⽅copy到设备的system中从⽽完成升级
如果升级失败可以在cache⽂件夹中看到log
升级成功后如果接收到按键消息,就会正常启动Android系统(就是正常升级后recovery命令会被删除掉)
4.kernel(初始化外设例如系统主频内存flash,系统驱动外设驱动统⼀都会被加载起来,根据uboot配置的参数来启动Android系统)
5.Android(系统启动后,初始化过程有分区挂载创建安卓相关⽬录,动态加载必要的驱动,根据启动脚本启动系统服务,相关环境变量配置例如硬软件版本,上诉全部完成安卓的启动服务会去守护系统以防中间有服务出错守护进程会重新创建服务)
(⼆)系统启动过程
1.启动脚本(init守护进程,启动脚本语法&分析&服务)
init进程在安卓源码的位置是system/core/init/init.c(在设备中没有看到这个物理地址)编译完成⽣成的init⽂件就放在设备的根⽬录下(车机ps之后只能看到两个进程没看到/init进程),各类⼿机⼚商会在⽂件中⾃⾏添加代码来达到⾃⼰常驻服务实现的⽬的(系统第⼀个应⽤进程,可以在进⼊adb shell的时候输⼊命令ps,可以查看到init信息的PID为1)
init进程主要⼯作:
1)根据安卓需求创建⽬录,挂载分区
2)解析启动脚本(服务操作以及⼀些环境变量的解析)
3)根据脚本设置来启动相关服务以及相关命令的执⾏
4)守护所有的服务
2.Zygote启动分析(⽀撑上层app,某些情况下会崩溃,init进程就会重新启动这个Zygote)
1)Zygote启动流程分析
2)java虚拟机启动 & 配置
3)Zygote启动分析(Zygote进程是被init进程启动的)
4)Zygote作⽤(Zygote进程会调⽤SystemServer.java中的main⽅法来创建单独的SystemServer进程)
3.SystemServer服务介绍
1) 启动进程PMS & AMS
在main⽅法中有调⽤SystemServer.run⽅法,在run⽅法中调⽤startBootstrapServices⽅法实例化AMS & PMS对象
其中PMS(Package Manager Service)占据系统开机时间的70%,这⾥是在PMS对象实例化过程中使⽤到的main⽅法⾥⾯有调⽤PMS类构建⽅法,并将这个service加⼊到SystemService中供其他类使⽤
主要⼯作是扫描系统软件⽬录与⾮系统软件⽬录,⼀般系统软件⽬录是/system/app/XXX,⽽⾮系统软件⽬录是/data/app/XXX,查看源码,在Environment类中定义android设备的⽬录,由PackagePartition类统⼀管理
在PackagePartition类中有⼀个内部类SystemPartition,在这个内部类的构造⽅法中定义了系统app的⽬录以及获取⽅法
然后通过⽅法scanDirTracedLI扫描这两个⽬录(实际调⽤ScanDirLI⽅法扫描这两个⽬录),在ScanDirLI⽅法中重点是调⽤ParallelPackageParser类submit⽅法将file中apk后缀⽂件解析为成员类型是ParserResult的ArrayBlockingQueue列表中
ParserResult类是ParallelPackageParser类的静态内部类,在submit⽅法中使⽤parsepackage⽅法获取返回值类型ParsedPackage,⽽这个类型是接⼝类型
继续查看mPackageParser.parsepackage⽅法,这个⽅法是PackageParser2类的⽅法parsePackage,这个⽅法的返回值是通过调⽤CachedResult
这个⽅法实际调⽤PackageCacher类的getCachedResult⽅法,这个⽅法是将file⽂件转换成byte类型⽂件并存储在Cache中,
这个⽅法的返回值是来⾃fromCacheEntry⽅法实际调⽤fromCacheEntryStatic,返回值实际是PackageImp类对象,这个类就是implements ParsedPackage接⼝的类
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论