android 启动流程 笔记

5 阅读4分钟

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进程
    
  • 关键步骤
    1. 初始化CPU、内存管理、进程调度等核心功能
    2. 加载驱动模块(驱动程序)
    3. 挂载根文件系统(rootfs)
    4. 启动第一个用户空间进程: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进程启动

  • 作用:应用进程的孵化器
  • 启动流程
    1. init进程解析init.zygote*.rc
    2. 启动/system/bin/app_process
    3. 调用AppRuntime.start()进入Java世界
// 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()
  • 流程
    1. AMS启动完成后调用startHomeActivityLocked()
    2. 解析Launcher的intent并启动
    3. 显示桌面界面

三、关键配置文件

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启动流程的特点

  1. 层次化设计:各层职责清晰,便于维护和扩展
  2. 并行启动:System Server中的服务并行初始化
  3. 懒加载机制:资源和类按需加载
  4. 缓存机制:Zygote预加载,减少应用启动时间
  5. 监控机制:BootReceiver收集启动信息

八、最新发展(Android 12+)

  1. Project Mainline:模块化系统组件,可独立更新
  2. Android Dynamic Partitions:动态分区管理
  3. ART AOT优化:更快的应用启动
  4. 启动画面优化:Splash Screen API标准化