文章目录
- 一、安卓打包流程专题
-
- [1. 简述从源码到最终APK生成的完整打包流程,涉及哪些关键工具链,各阶段的输入输出是什么?**](#1. 简述从源码到最终APK生成的完整打包流程,涉及哪些关键工具链,各阶段的输入输出是什么?**)
- [2. aapt2相比传统aapt在资源编译上有哪些改进?资源的编译、链接、打包具体是如何进行的?](#2. aapt2相比传统aapt在资源编译上有哪些改进?资源的编译、链接、打包具体是如何进行的?)
- [3. R.java/ResourceTable是如何生成的?在代码中引用资源ID的原理是什么?](#3. R.java/ResourceTable是如何生成的?在代码中引用资源ID的原理是什么?)
- [4. Java/Kotlin代码是如何被编译为Class文件,再通过D8/R8转换为DEX文件的?多DEX分包在哪个阶段处理?](#4. Java/Kotlin代码是如何被编译为Class文件,再通过D8/R8转换为DEX文件的?多DEX分包在哪个阶段处理?)
- [5. Proguard/R8混淆的原理是什么?混淆配置文件中keep规则的作用及常见配置场景?](#5. Proguard/R8混淆的原理是什么?混淆配置文件中keep规则的作用及常见配置场景?)
- [6. APK签名(V1、V2、V3)的区别是什么?为什么Google推荐使用V2签名?V2签名对APK结构有何影响?](#6. APK签名(V1、V2、V3)的区别是什么?为什么Google推荐使用V2签名?V2签名对APK结构有何影响?)
- [7. 简述Android App Bundle (AAB) 的打包原理,相比传统APK有什么优势?](#7. 简述Android App Bundle (AAB) 的打包原理,相比传统APK有什么优势?)
- [8. 打包过程中,assets目录与res目录的处理方式有何不同?为什么assets不会生成资源ID?](#8. 打包过程中,assets目录与res目录的处理方式有何不同?为什么assets不会生成资源ID?)
- [9. 什么是zipalign对齐?它在打包流程的哪个阶段执行?不执行对齐会有什么问题?](#9. 什么是zipalign对齐?它在打包流程的哪个阶段执行?不执行对齐会有什么问题?)
- [10. Gradle构建脚本中,transform API的作用是什么?通常被用于哪些场景?](#10. Gradle构建脚本中,transform API的作用是什么?通常被用于哪些场景?)
- [11. APK由哪部分构成?](#11. APK由哪部分构成?)
- 二、点击APP图标到启动全流程专题
-
- [1. 详细描述从点击桌面Launcher图标到MainActivity的onResume执行完成的全过程,重点阐述交互逻辑。**](#1. 详细描述从点击桌面Launcher图标到MainActivity的onResume执行完成的全过程,重点阐述交互逻辑。**)
- [2. 冷启动场景下,系统是如何通过Zygote孵化出新进程的?ActivityThread.main()是应用进程入口吗?**](#2. 冷启动场景下,系统是如何通过Zygote孵化出新进程的?ActivityThread.main()是应用进程入口吗?**)
- [3. 应用进程启动后,ActivityThread如何与AMS双向通信?Application的onCreate在哪个时机调用?](#3. 应用进程启动后,ActivityThread如何与AMS双向通信?Application的onCreate在哪个时机调用?)
- [4. 冷启动、热启动、温启动的定义及区别,生命周期回调有何不同? **](#4. 冷启动、热启动、温启动的定义及区别,生命周期回调有何不同? **)
- [5. 应用启动白屏/黑屏的原因是什么?如何优化启动速度?](#5. 应用启动白屏/黑屏的原因是什么?如何优化启动速度?)
- [6. 系统内存不足时,点击图标重启应用,和正常冷启动有何差异?](#6. 系统内存不足时,点击图标重启应用,和正常冷启动有何差异?)
- [7. Intent在应用启动流程中的传递路径?隐式Intent如何匹配到目标Activity?](#7. Intent在应用启动流程中的传递路径?隐式Intent如何匹配到目标Activity?)
- [8. AMS如何调度Activity生命周期(onCreate→onStart→onResume)](#8. AMS如何调度Activity生命周期(onCreate→onStart→onResume))
- [9. 应用启动时,Window如何被创建并显示?WMS扮演什么角色?](#9. 应用启动时,Window如何被创建并显示?WMS扮演什么角色?)
- [10. 启动优化中异步初始化和懒加载的含义,分别优化哪个阶段耗时?](#10. 启动优化中异步初始化和懒加载的含义,分别优化哪个阶段耗时?)
- [11. 深入理解Instrumentation、ActivityThread、ActivityManagerService 三者之间的协作关系 ***](#11. 深入理解Instrumentation、ActivityThread、ActivityManagerService 三者之间的协作关系 ***)
- 三、安卓系统启动流程专题
-
- [1. 简述安卓设备从按下电源键到Launcher桌面显示的完整系统启动流程。**](#1. 简述安卓设备从按下电源键到Launcher桌面显示的完整系统启动流程。**)
- [2. Linux内核启动后,第一个用户进程是什么?作用是什么?**](#2. Linux内核启动后,第一个用户进程是什么?作用是什么?**)
- [3. Zygote进程如何被启动?与SystemServer进程的关系是什么?**](#3. Zygote进程如何被启动?与SystemServer进程的关系是什么?**)
- [4. SystemServer进程启动后,会初始化哪些核心系统服务?](#4. SystemServer进程启动后,会初始化哪些核心系统服务?)
- [5. 简述PMS在系统启动阶段的主要工作。](#5. 简述PMS在系统启动阶段的主要工作。)
一、安卓打包流程专题
1. 简述从源码到最终APK生成的完整打包流程,涉及哪些关键工具链,各阶段的输入输出是什么?**
- 标准答案:
安卓APK打包是一套标准化的编译构建流程,整体分为资源编译、源码编译、字节码转换、打包、签名、对齐这几个核心阶段。
- 第一步,资源编译:通过aapt2编译res目录下的资源文件,生成编译后的二进制资源、资源索引表,同时生成R文件,把资源ID映射到代码中,assets资源直接复制不编译。
- 第二步,源码编译:用javac编译器,把Java/Kotlin源码以及R文件、依赖库编译成Class字节码文件。
- 第三步,字节码转换:通过D8/R8工具,将Class文件转换成DEX文件,同时处理类压缩、方法数超限问题,多DEX分包也在这一阶段处理。
- 第四步,打包生成未签名APK:把二进制资源、DEX文件、so库、assets文件等,打包成一个未签名的压缩包,也就是初始APK。
- 第五步,APK签名:对APK进行V1/V2/V3签名,校验包完整性、防止篡改,保证包来源可信。
- 第六步,对齐优化:通过zipalign工具,对APK内部文件进行4字节对齐,减少运行时内存占用,加快读取速度。
核心工具链:aapt2(资源编译)、javac(源码编译)、D8/R8(DEX转换+混淆)、apksigner(签名)、zipalign(对齐)。
- 速记思路:
资源编译→源码转Class→Class转DEX→打包→签名→对齐,记清六步和对应工具。
2. aapt2相比传统aapt在资源编译上有哪些改进?资源的编译、链接、打包具体是如何进行的?
- 标准答案 :
aapt2是谷歌推出的新一代资源编译工具,拆分了编译和链接流程,相比老版aapt,核心改进有三点。第一,支持增量编译 ,只编译修改过的资源,大幅提升增量构建速度,老版aapt是全量编译,效率低下。第二,修复了大量资源合并冲突、命名冲突问题,兼容性更强。第三,资源编译更严格,能提前暴露资源错误,减少运行时异常。
资源编译环节:单独编译每一个资源文件,生成二进制资源文件和中间产物,不会合并资源。链接环节:把所有编译后的二进制资源、库文件资源合并在一起,生成最终的资源索引表和完整资源包,再对接源码编译环节。 - 速记思路 :
增量编译、拆分编译链接、报错更严格,两步走:先编译单个资源,再统一链接。
3. R.java/ResourceTable是如何生成的?在代码中引用资源ID的原理是什么?
- 标准答案 :
R文件由aapt2在资源编译阶段自动生成,属于自动生成的常量类。系统会给res目录下每一个资源(布局、图片、字符串、颜色等)分配一个唯一的十进制常量ID,把资源名和ID一一对应,写入R类中,分为不同内部类(layout、drawable、string等)归类存放。
在代码中引用资源,其实是引用R类里的常量ID,AMS、WMS等系统服务会通过这个ID,在资源索引表里面查找对应的二进制资源,完成加载和渲染。在Android Studio升级后,新版AS用ResourceTable替代了传统R.java,原理一致,只是存储形式更轻量化,更适配模块化开发。 - 速记思路 :
aapt2自动生成,资源对应唯一ID,代码用ID查表找资源。
4. Java/Kotlin代码是如何被编译为Class文件,再通过D8/R8转换为DEX文件的?多DEX分包在哪个阶段处理?
- 标准答案:
首先,Kotlin代码会通过kotlinc编译器先编译成Java代码,再和原生Java代码一起,由javac编译成Class字节码文件,这一步和普通Java项目编译一致。
随后,D8/R8工具会对所有Class文件进行处理,把Class字节码转换成安卓虚拟机支持的DEX字节码。安卓单个DEX文件有65536个方法数限制,超出后会报错。
多DEX分包在D8/R8转换阶段处理,Gradle开启multiDexEnabled之后,工具会自动把代码拆分到多个DEX文件中,打包时一起打入APK,应用启动时再加载全部DEX文件,解决方法数超限问题。
- 速记思路:
Kotlin转Java→javac转Class→D8/R8转DEX,DEX超限,分包在D8/R8阶段处理。
5. Proguard/R8混淆的原理是什么?混淆配置文件中keep规则的作用及常见配置场景?
- 标准答案
混淆核心原理有三个,分别是压缩、优化、混淆 。压缩是移除无用代码、无用资源、未调用的类和方法,减小包体积。优化是对字节码进行优化,简化逻辑、去除冗余代码。混淆是把类名、方法名、字段名替换成无意义的短字符(如a、b、c),防止逆向工程破解代码,同时进一步缩小包体积。
keep规则用于保留指定类、方法、字段不被混淆和移除。常见场景:四大组件、自定义View、JNI调用的Java方法、反射用到的类、序列化实体类、第三方SDK代码,这些都必须加keep规则,否则会出现类找不到、方法调用失败等崩溃问题。 - 速记思路
压缩+优化+混淆,keep保留不能混淆的代码,记牢四类必保留场景。
6. APK签名(V1、V2、V3)的区别是什么?为什么Google推荐使用V2签名?V2签名对APK结构有何影响?
- 标准答案 :
V1签名是传统Jar签名,只对APK内的单个文件签名校验,不对整个APK包校验,安全性低,修改APK内部文件后仍能通过校验,而且签名校验速度慢。
V2签名是全包签名,在APK完整结构上增加签名区块,对整个APK内容进行校验,安全性极高,防止包被篡改、二次打包,校验速度更快,安卓7.0以上系统支持。
V3签名在V2基础上,支持密钥轮转,更换签名密钥后仍能校验通过,适配应用更换签名的场景,兼容性更强。
Google推荐V2签名,是因为安全性更高、校验更快,能有效防止恶意篡改。V2签名会改变APK结构,在原APK数据区和签名区之间增加专属签名块,不破坏原有文件结构。 - 速记思路 :
V1(文件签名、不安全)→V2(全包签名、安全)→V3(支持换密钥),V2更安全是核心。
7. 简述Android App Bundle (AAB) 的打包原理,相比传统APK有什么优势?
- 标准答案
AAB是谷歌推出的新一代应用打包格式,替代传统APK。开发者打包生成AAB包,上传到Google Play商店,商店会根据用户设备的CPU架构、屏幕分辨率、语言等配置,自动拆分生成对应的轻量化APK ,再推送给用户。
相比传统APK,优势很明显:第一,大幅减小安装包体积,剔除设备不需要的资源和so库;第二,开发者只需打包一个AAB包,不用适配多套APK;第三,减少冗余资源,降低下载失败率,提升安装效率。 - 速记思路
打一个AAB包,商店按需拆分包,体积更小、适配更方便。
8. 打包过程中,assets目录与res目录的处理方式有何不同?为什么assets不会生成资源ID?
- 标准答案
res目录资源会由aapt2编译、索引,自动生成R文件ID ,代码通过ID直接引用,系统会对资源进行优化、压缩、适配。
assets目录资源属于原生静态资源,打包时直接复制到APK ,不参与编译、不生成资源ID,不会被系统优化和筛选,保留原文件格式和路径。
assets不生成ID,是因为它属于文件目录形式存储,适合存放大量静态文件、自定义格式文件,代码需要通过AssetManager类,用文件路径去加载,而非资源ID。 - 速记思路
res编译+生成ID,assets直接复制+无ID,用路径加载。
9. 什么是zipalign对齐?它在打包流程的哪个阶段执行?不执行对齐会有什么问题?
- 标准答案:
zipalign是APK对齐优化工具 ,对APK内部所有资源文件进行4字节边界对齐,让文件数据从固定偏移量开始存储。
它在APK签名完成之后执行,属于打包最后一步优化。如果不执行对齐,系统加载APK资源时,需要额外计算偏移量,会占用更多内存,资源读取速度变慢,严重时会出现内存溢出,甚至部分系统无法正常安装应用。 - 速记思路:
签名后执行,4字节对齐,不对齐会卡顿、耗内存、安装失败。
10. Gradle构建脚本中,transform API的作用是什么?通常被用于哪些场景?
标准答案:transform API是Gradle提供的字节码处理接口,在Class文件转换为DEX文件之前执行,用于对Class字节码进行自定义修改、插入、删除操作。
它属于编译时插桩技术,常见场景:代码埋点统计、性能监控、日志插入、权限拦截、热修复框架、组件化路由注入等,不需要修改源码,就能在编译阶段完成代码增强。
速记思路:编译时修改字节码,用于插桩、埋点、热修复、路由注入。
11. APK由哪部分构成?
- AndroidManifest.xml:配置文件,包含应用的基本信息,如包名、组件(Activity、Service、BroadcastReceiver等)、权限声明等。
- classes.dex:Dalvik字节码文件,包含应用的Java/Kotlin代码编译后的可执行文件。
- resources.arsc:编译后的资源索引文件,包含资源ID与资源值的映射。
- res/:资源目录,包含布局文件、图片、字符串、样式等资源。
- assets/:原始资源目录,存放应用运行时需要访问的原始文件(如音视频、HTML文件等)。
- lib/:包含应用使用的本地库文件(如.so文件),按不同CPU架构分类存放。
- META-INF/:签名信息目录,包含证书(CERT.RSA/DSA)和摘要文件(MANIFEST.MF)等。
二、点击APP图标到启动全流程专题
【Android Activity启动流程】启动流程深入理解

1. 详细描述从点击桌面Launcher图标到MainActivity的onResume执行完成的全过程,重点阐述交互逻辑。**
标准答案:
- 第一步,用户点击桌面图标,Launcher作为系统桌面应用,会发出一个隐式Intent,包含启动入口Activity的action和category信息。
- 第二步,Intent通过Binder跨进程通信,传递给系统核心服务AMS(ActivityManagerService),AMS负责Activity的生命周期调度和进程管理。
- 第三步,AMS先通过PMS(PackageManagerService)校验APP是否存在、入口Activity是否配置,随后检查应用进程是否存在。
- 第四步,如果进程不存在,AMS请求Zygote进程,孵化出应用独立进程,Zygote是所有应用进程的父进程,负责复制虚拟机和系统资源。
- 第五步,应用进程启动后,执行ActivityThread的main方法,初始化主线程、Looper、Application,调用Application的onCreate方法。
- 第六步,ActivityThread通过Binder向AMS汇报进程启动完成,AMS下发生命周期调度指令,依次执行入口Activity的onCreate、onStart、onResume方法。
- 第七步,onResume执行后,WMS(WindowManagerService)创建Window并绘制界面,应用正式显示。
速记思路:
点击图标→Launcher发Intent→AMS校验→Zygote孵化进程→初始化Application→Activity生命周期→界面显示。
2. 冷启动场景下,系统是如何通过Zygote孵化出新进程的?ActivityThread.main()是应用进程入口吗?**
- 标准答案:
冷启动时应用进程未创建,AMS通过Socket通信,向Zygote进程发送创建请求。
Zygote采用fork机制,复制自身进程空间,生成新的应用子进程,继承虚拟机环境、系统库、基础资源,不用重新初始化,提升启动速度。
ActivityThread的main方法,是应用进程的Java层入口,属于主线程入 口。进程启动后,系统会反射调用main方法,内部初始化主线程Looper,开启消息循环,同时绑定Application,完成进程初始化,是应用代码执行的起点。 - 速记思路:
AMS请求→Zygote fork进程,main方法是Java层入口,初始化Looper。
3. 应用进程启动后,ActivityThread如何与AMS双向通信?Application的onCreate在哪个时机调用?
- 标准答案:
ActivityThread和AMS通过Binder机制 实现双向通信。AMS持有应用进程的Binder代理(IApplicationThread),用于下发生命周期、进程调度指令;应用进程持有AMS的Binder代理,用于向AMS汇报状态、请求系统服务。
Application的onCreate调用时机:进程fork完成、主线程初始化完毕、Binder通信建立之后,Activity生命周期开始之前。这是应用代码最早执行的回调,用于全局初始化、SDK配置。 - 速记思路:
Binder双向通信,AMS发指令,App回状态,onCreate在Activity启动前。
4. 冷启动、热启动、温启动的定义及区别,生命周期回调有何不同? **
标准答案:
- 冷启动:应用进程完全销毁,点击图标重新启动,流程最全,耗时最长。会走进程创建、Application初始化、Activity全生命周期(onCreate→onStart→onResume)。
- 热启动:应用进程存活,Activity在后台,只是退到后台,点击图标回到前台。不会重建进程和Application,Activity不会走onCreate,只执行onRestart→onStart→onResume。
- 温启动:介于两者之间,进程存活,但Activity被系统回收。点击启动时,不会重建进程,会重新创建Activity,执行onCreate→onStart→onResume。
速记思路:
- 冷启动(全重来)、热启动(只恢复)、温启动(重建页面),记清生命周期差异。
5. 应用启动白屏/黑屏的原因是什么?如何优化启动速度?
标准答案:
- 白屏/黑屏产生原因:启动时,系统会先加载应用清单文件里的主题背景,默认主题是黑色或白色,此时Application和Activity还没初始化,界面未绘制,就会出现空白窗口。
- 启动优化方向:第一,减少Application onCreate里的耗时操作,同步操作改异步,非核心初始化懒加载;第二,设置启动页背景,替换默认白屏,提升视觉体验;第三,优化布局层级,减少onCreate里的耗时操作;第四,避免启动时IO操作、网络请求、大量GC;第五,合理使用多线程,拆分初始化任务。
速记思路:
- 空白窗口导致黑屏白屏,优化:懒加载、异步、换启动背景、减耗时。
6. 系统内存不足时,点击图标重启应用,和正常冷启动有何差异?
- 标准答案:
正常冷启动是用户手动杀死进程,或进程完全销毁,启动流程完整,数据完全重置。内存不足触发的启动,属于系统强制回收进程,应用会保存临时状态和页面栈 。
差异点:第一,系统会尝试恢复之前的Activity栈,而不是直接启动入口Activity;第二,会触发Activity的状态恢复逻辑,执行onRestoreInstanceState;第三,Application不会重复初始化;第四,可能出现数据丢失、页面恢复异常,需要做好状态保存和容错处理。 - 速记思路:
正常冷启动全重置,内存不足重启会恢复页面栈、保存状态。
7. Intent在应用启动流程中的传递路径?隐式Intent如何匹配到目标Activity?
- 标准答案:
传递路径:用户点击图标→Launcher生成Intent→Launcher进程跨进程传给AMS→AMS校验Intent→AMS分发到应用进程→Activity接收Intent。
隐式Intent匹配逻辑:AMS通过PMS,扫描所有已安装应用的清单文件,匹配Intent里的action、category、data,找到注册了对应过滤规则的Activity,确认唯一目标组件,再完成跳转。如果匹配到多个,会弹出选择框。
- 速记思路:
Launcher→AMS→应用进程,PMS匹配清单过滤规则找到页面。
8. AMS如何调度Activity生命周期(onCreate→onStart→onResume)
- 标准答案:
AMS作为系统服务,统一管理所有应用的Activity生命周期,通过Binder指令控制。
进程启动完成后,AMS先判断Activity状态,处于未创建状态,先下发onCreate指令,完成页面初始化、布局加载。
onCreate执行完毕,AMS下发onStart指令,页面变为可见状态,但无法交互。随后下发onResume指令,页面获取焦点,可响应触摸事件,彻底显示。
整个流程由AMS主动调度,ActivityThread接收指令,反射调用对应的生命周期方法,保证生命周期执行顺序严格有序。 - 速记思路:
AMS发指令,ActivityThread执行,按create→start→resume顺序执行。
9. 应用启动时,Window如何被创建并显示?WMS扮演什么角色?
- Activity 启动请求
应用通过调用 startActivity() 发起启动请求,系统会通过 ActivityManagerService(AMS) 来处理这个请求,并启动目标 Activity。 - 创建 PhoneWindow 和 DecorView
当目标 Activity 被创建时,系统会为其创建一个 PhoneWindow 实例(Window 的具体实现类),并通过 setContentView() 设置布局内容,最终生成 DecorView,也就是整个界面的根视图。 - ViewRootImpl 初始化并连接 WMS
在 ActivityThread 执行 handleResumeActivity() 时,会通过 WindowManager 将 DecorView 添加到系统中。这时会创建 ViewRootImpl,它是连接 View 层与 WMS 的核心类。 - WMS 接收添加窗口请求
WMS 会为这个窗口分配唯一的 token,确定窗口层级(Z-order),并进行布局计算。同时,WMS 会与 SurfaceFlinger 通信,为窗口分配一块绘图的 Surface。 - 执行测量、布局与绘制流程
ViewRootImpl 会触发 performTraversals(),依次执行 measure、layout、draw 流程,将 UI 内容绘制到 Surface 上。 - 最终显示在屏幕上
SurfaceFlinger 负责将所有窗口的图形缓冲区进行合成,并送显到屏幕上,最终用户可以看到应用界面。
10. 启动优化中异步初始化和懒加载的含义,分别优化哪个阶段耗时?
- 标准答案:
异步初始化 :把Application和Activity onCreate里的同步耗时操作,放到子线程执行,不阻塞主线程,不影响生命周期执行,优化主线程阻塞时间,加快页面显示。主要优化进程初始化、Application onCreate阶段的耗时。
懒加载:核心是延迟加载,非核心资源、非立即显示的数据、页面,推迟到页面显示后、用户交互时再加载,不占用启动时段资源。主要优化Activity onCreate、onResume阶段的耗时,减少启动时的工作量,缩短启动时间。 - 速记思路:
异步(子线程做耗时,不卡主线程),懒加载(延后加载,不抢启动时间)。
11. 深入理解Instrumentation、ActivityThread、ActivityManagerService 三者之间的协作关系 ***
可以参考前面的流程图
-
组件职责简介:
ActivityManagerService(AMS)
系统级服务 ,运行在 System Server 进程中。负责管理四大组件的生命周期、任务栈管理、进程调度等。
接收来自应用端的启动请求,并决定目标 Activity 的启动时机与方式。
ActivityThread应用的主线程,是应用进程的入口。
内部通过 H(Handler)处理来自 AMS 的消息,如 LAUNCH_ACTIVITY、PAUSE_ACTIVITY 等。
负责调用 performLaunchActivity() 启动 Activity。
Instrumentation用于监控 Activity 的生命周期和系统交互,支持单元测试。
一个应用进程中通常只有一个 Instrumentation 实例
提供 newActivity()、callActivityOnCreate() 等方法,用于创建和管理 Activity 实例。
在 Activity 启动过程中,真正调用其生命周期方法。
-
启动流程中的协作关系:
-
AMS 接收启动请求
应用调用 startActivity() 后,会通过 Binder 调用到 AMS 的 startActivity() 方法。
-
AMS 决定启动目标 Activity
AMS 会检查目标 Activity 的状态、任务栈、权限等信息,并决定是否需要新建进程或复用已有进程。
-
AMS 向目标进程发送 LAUNCH_ACTIVITY 消息
如果目标进程已启动,则 AMS 通过 Binder 向该进程的 ActivityThread 发送 LAUNCH_ACTIVITY 消息。
-
ActivityThread 处理消息并调用 Instrumentation
ActivityThread 中的 H 接收到消息后,调用 handleLaunchActivity(),进而调用 Instrumentation.newActivity() 创建 Activity 实例。
-
Instrumentation 调用生命周期方法
Instrumentation 会调用 callActivityOnCreate()、callActivityOnStart()、callActivityOnResume() 等方法,完成 Activity 的生命周期初始化。
-
最终完成显示
在 onResume() 中,会执行 Activity.makeVisible(),触发 ViewRootImpl 的创建,最终完成窗口的显示。
-
总结:
AMS 是"指挥官":负责全局调度,决定何时启动哪个 Activity。
ActivityThread 是"执行者":接收 AMS 指令,调度执行具体操作。
Instrumentation 是"代理":负责实际创建 Activity 实例并调用其生命周期方法。
三、安卓系统启动流程专题
1. 简述安卓设备从按下电源键到Launcher桌面显示的完整系统启动流程。**
- 标准答案:
开机自检:按下电源键,设备执行BootROM引导,加载BootLoader程序,初始化硬件,启动Linux内核。
内核启动:Linux内核加载完成,初始化进程管理器、内存管理、驱动程序,启动第一个用户进程init进程。
init进程启动:解析init.rc脚本,创建系统目录,启动各类系统守护进程,孵化Zygote进程。
Zygote进程启动:初始化Java虚拟机,注册系统服务,预加载系统资源和类,监听AMS请求,等待孵化应用进程。
SystemServer进程启动:Zygote fork出SystemServer,这是系统核心服务进程,启动AMS、WMS、PMS等核心服务。
启动桌面:系统服务初始化完毕,SystemServer启动Launcher桌面应用,设备开机完成,显示桌面。 - 速记思路:
开机→内核→init→Zygote→SystemServer→核心服务→Launcher
2. Linux内核启动后,第一个用户进程是什么?作用是什么?**
标准答案:
Linux内核启动后,第一个用户进程是init进程,进程号为1,是所有用户进程的祖进程。
核心作用:初始化系统环境,解析启动脚本,创建系统文件夹,加载硬件驱动,启动系统守护进程,fork孵化Zygote进程,管控系统进程的创建和销毁,保证系统基础运行环境。
速记思路:
init是1号进程,初始化系统,孵化Zygote
3. Zygote进程如何被启动?与SystemServer进程的关系是什么?**
- 标准答案:
Zygote进程由init进程,通过解析init.rc脚本启动,属于系统级核心进程。Zygote是所有应用进程的父进程,采用fork机制创建应用子进程。
SystemServer进程由Zygote进程fork生成,是系统最重要的服务进程,负责启动和管理所有系统服务。两者是父子进程关系,Zygote负责孵化应用进程,SystemServer负责运行系统服务。 - 速记思路:
init启动Zygote,Zygote fork出SystemServer(不止这一个进程),父子进程。
4. SystemServer进程启动后,会初始化哪些核心系统服务?
- 标准答案:
SystemServer启动后,会初始化一系列系统核心服务,高频核心服务有:AMS(ActivityManagerService,管理四大组件生命周期、进程调度)、WMS(WindowManagerService,窗口管理、界面显示)、PMS(PackageManagerService,应用安装、卸载、包信息管理)。
除此之外,还有IMS(输入管理服务)、电池管理服务、网络管理服务、通知管理服务等,共同支撑整个安卓系统运行。 - 速记思路:
核心三大服务:AMS、WMS、PMS,再补充其他辅助服务。
5. 简述PMS在系统启动阶段的主要工作。
标准答案:
PMS是包管理服务,系统启动阶段核心工作:
第一,扫描系统目录、应用安装目录,解析所有APK的清单文件;
第二,解析应用权限、四大组件、版本信息,缓存包信息;
第三,完成应用安装、注册、权限校验;
第四,对外提供包查询、组件匹配能力,供AMS等服务调用。
速记思路:
扫描APK→解析清单→缓存信息→管理包和权限。

