Android 开发核心面试题解析
一、Android 系统启动流程详解
当用户按下电源键触发开机时,Android 系统的启动过程涉及多个关键阶段:
- BootLoader 加载:从 ROM 中预定义的位置加载引导程序 BootLoader 到 RAM 中。
- 内核启动:执行 BootLoader 程序启动 Linux Kernel。
- Init 进程:启动用户级别的第一个进程
init。该进程会解析init.rc脚本进行初始化工作,包括挂载文件系统、创建工作目录以及启动系统服务进程(如 Zygote、Service Manager、Media 等)。 - Zygote 孵化:在 Zygote 进程中进一步启动
system_server进程。 - 系统服务启动:在
system_server进程中启动 AMS(Activity Manager Service)、WMS(Window Manager Service)、PMS(Package Manager Service)等核心服务。 - 桌面显示:服务启动完成后,AMS 打开 Launcher 应用的 Home Activity,最终呈现手机桌面。
二、System_Server 为何在 Zygote 中启动
system_server 选择在 Zygote 中启动而非由 init 直接启动,主要基于以下原因:
- 资源复用:Zygote 作为一个孵化器,提前加载了部分资源(如 JNI 函数、共享库、常用类、主题资源)。
- Copy-On-Write (COW):通过 fork() 机制创建其他进程时,利用 COW 机制可以直接使用这些资源,无需重新加载,显著提升了应用启动速度。
三、Zygote 与 System_Server 的分工
为什么不直接使用 system_server 去孵化应用进程?
- 职责分离:
system_server运行了 AMS、WMS 等服务,这对普通应用程序是不必要的负担。 - 多线程 Fork 风险:进程的
fork()对多线程不友好。它仅将发起调用的线程拷贝到子进程。如果父进程存在多线程,可能导致死锁。system_server内部包含大量线程,不适合直接用于 fork 新进程。
死锁机制分析
在 POSIX 标准中,fork() 复制整个用户空间数据及所有系统对象。若父进程中某子线程持有锁,fork() 后子进程中该线程消失但锁状态被保留。子进程尝试获取该锁时将无法解锁,导致死锁。
四、Binder 通信机制优势
Binder 是 Android 特有的 IPC(进程间通信)机制,相比传统方式具有显著优势:
1. 性能方面
- 共享内存:0 次数据拷贝。
- Binder:1 次数据拷贝。
- Socket/管道:2 次数据拷贝。
2. 稳定性方面
- Binder 基于 C/S 架构,客户端与服务端职责明确且相互独立。
- 共享内存控制复杂,难以维护。
3. 安全性方面
- 传统 IPC 缺乏安全措施,依赖上层协议。
- 传统 IPC 无法可靠获取对方 UID/PID,易被恶意程序利用。
- Binder 支持实名和匿名 Binder,具备高安全性。

