Android 启动流程原理分析
Android 启动流程是一个复杂但高度模块化的过程,从按下电源键到应用启动,涉及多个层次的协同工作。以下是详细的启动流程分析:
一、整体启动流程概览
Boot ROM → Bootloader → Linux Kernel → Init进程 → Zygote → System Server → Launcher
二、详细启动流程分析
1. Boot ROM(引导芯片)
- 作用:设备上电后执行的第一段代码
- 位置:固化在CPU内部ROM中
- 功能:
- 初始化硬件,确保最小系统运行
- 加载Bootloader到内存并执行
2. Bootloader(引导加载程序)
- 主要Bootloader:通常是U-Boot或设备厂商定制版本
- 功能:
- 检测外设和内存
- 设置Linux内核启动参数
- 加载kernel和ramdisk到内存
- 跳转到内核执行
3. Linux Kernel启动阶段
- 初始化过程:
内核入口 → 设置缓存/内存 → 初始化驱动 → 挂载根文件系统 → 启动init进程 - 关键步骤:
- 初始化CPU、内存管理、进程调度等核心功能
- 加载驱动模块(驱动程序)
- 挂载根文件系统(rootfs)
- 启动第一个用户空间进程:init(PID=1)
4. Init进程初始化
- 位置:
/system/core/init/ - 主要任务:
// init.cpp 主要流程简化
int main() {
// 1. 创建和挂载文件系统
mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
// 2. 初始化内核日志
klog_init();
// 3. 初始化属性系统
property_init();
// 4. 解析init.rc配置文件
LoadBootScripts();
// 5. 执行启动服务
while (true) {
// 执行命令/启动服务
execute_one_command();
// 处理属性变更
handle_property_set_fd();
// 处理信号
handle_signal();
}
}
5. Zygote进程启动
- 作用:应用进程的孵化器
- 启动流程:
- init进程解析
init.zygote*.rc - 启动
/system/bin/app_process - 调用
AppRuntime.start()进入Java世界
- init进程解析
// ZygoteInit.java 关键代码
public static void main(String[] argv) {
// 1. 预加载资源和类
preload();
// 2. 启动System Server
if (startSystemServer) {
forkSystemServer();
}
// 3. 进入Socket循环,监听应用启动请求
runSelectLoop();
}
6. System Server启动
- 位置:
frameworks/base/services/java/com/android/server/ - 启动流程:
// SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
// 1. 启动引导服务
startBootstrapServices();
// 2. 启动核心服务
startCoreServices();
// 3. 启动其他服务
startOtherServices();
// 4. 进入Loop循环
Looper.loop();
}
7. Launcher启动
- 触发时机:
ActivityManagerService.systemReady() - 流程:
- AMS启动完成后调用
startHomeActivityLocked() - 解析Launcher的intent并启动
- 显示桌面界面
- AMS启动完成后调用
三、关键配置文件
1. init.rc文件结构
import /init.${ro.hardware}.rc
# 定义服务
service zygote /system/bin/app_process
class main
socket zygote stream 660 root system
service servicemanager /system/bin/servicemanager
class core
# 触发器和动作
on early-init
mkdir /dev/socket
on property:sys.boot_completed=1
start bootcomplete
2. Zygote的Socket通信
# 客户端(AMS)请求创建进程
ZygoteProcess.connect(): 连接到Zygote Socket
ZygoteProcess.start(): 发送启动参数
ZygoteConnection.processCommand(): 处理请求并fork进程
四、启动优化技术
1. 应用预加载
// ZygoteInit.java
static void preload() {
preloadClasses(); // 预加载常用类
preloadResources(); // 预加载资源
preloadOpenGL(); // 预初始化图形库
preloadSharedLibraries(); // 预加载共享库
}
2. 启动时间优化
- 内核优化:减少不必要的驱动初始化
- 并行启动:服务并行初始化
- 延迟启动:非关键服务延后加载
- 应用优化:
- 多Dex文件优化
- 资源按需加载
- 启动器应用优化
五、启动性能分析工具
1. Bootchart
# 启用bootchart
adb shell 'touch /data/bootchart/enabled'
# 获取数据
adb pull /data/bootchart/
2. Systrace
# 捕获启动trace
python systrace.py --time=10 -o boot.html sched gfx view
3. 内核日志分析
dmesg | grep -E "init|boot|start"
六、常见问题与调试
1. 启动卡住排查
# 查看当前进程
adb shell ps -A | head -20
# 查看init日志
adb logcat -b events | grep "boot_progress"
# 检查服务状态
adb shell dumpsys activity services
2. 启动阶段时间统计
Bootloader: 1-3秒
Linux Kernel: 2-5秒
Init进程: 1-2秒
Zygote启动: 0.5-1秒
System Server: 3-8秒
Launcher显示: 1-2秒
七、Android启动流程的特点
- 层次化设计:各层职责清晰,便于维护和扩展
- 并行启动:System Server中的服务并行初始化
- 懒加载机制:资源和类按需加载
- 缓存机制:Zygote预加载,减少应用启动时间
- 监控机制:BootReceiver收集启动信息
八、最新发展(Android 12+)
- Project Mainline:模块化系统组件,可独立更新
- Android Dynamic Partitions:动态分区管理
- ART AOT优化:更快的应用启动
- 启动画面优化:Splash Screen API标准化