Android启动优化

一. 核心优化思路

开机过程主要分为以下几个阶段,优化也围绕这些阶段展开:

  1. Bootloader:初始化硬件,加载内核。通常由芯片厂商定制,优化空间有限
  2. Kernel:初始化驱动、子系统。优化重点在于减少初始化时间和裁剪不必要的驱动
  3. Init 进程 :解析 init.rc 脚本,启动核心系统服务(如 servicemanager, surfaceflinger)
  4. Zygote 进程:Android 运行时和系统服务的孵化器。预加载类和资源,其启动速度直接影响后续应用启动
  5. SystemServer :Android 框架的核心,启动所有系统服务(如 AMS, PMS, WMS 等)。这是优化潜力最大、最复杂的阶段
  6. Launcher:系统启动完成的标志,启动主屏幕应用

核心思想并行化、延迟加载、缓存、裁剪

二. 具体优化方法

阶段 一:内核与 Init 阶段优化
  1. 内核配置优化
    裁剪内核 :移除设备不需要的驱动、文件系统、网络协议、调试功能等。使用 make menuconfig 进行精细配置
    优化内核启动参数 :调整控制台输出、内存管理等参数
    初始化调用优化 :将非关键的驱动初始化(module_init)标记为延迟初始化late_initcall),使其在系统启动后再初始化
  2. Init 阶段优化
    并行执行任务 :修改 init.rc 文件,利用 class_start 将不相互依赖的服务标记为同一个 class,让 init 进程并行启动它们
    减少 Shell 命令 :避免在 init.rc 中执行耗时的 Shell 命令(如 chmod, chown 等),这些操作应在编译时由 fs_config 完成
    使用 Treble 和 A/B 分区:Treble 架构将系统和供应商解耦,简化了更新流程。A/B(无缝更新)分区可以让系统在后台更新,下次启动直接切换到新系统,减少感知到的启动时间
阶段 二:Zygote 优化
  1. 预加载优化
    分析预加载类 :使用工具分析 Zygote 预加载的类和资源。移除系统级应用不再使用的类,减少预加载列表(如 preloaded-classes
    优化预加载逻辑:避免在预加载阶段执行复杂的逻辑或 I/O 操作
  2. Zygote 本身优化
    ○ 关注 AOSP 上游的改进。例如,Android 10 引入了 App ZygoteUSAP(未知应用预孵化池),进一步优化了应用启动,但其本身的初始化也需要优化
阶段 三:SystemServer 优化 - 重中之重

这是最复杂也是收益最高的部分

  1. 服务启动分析
    ○ 使用 dumpsys package startup-info 或直接查看 SystemServer 的日志,了解各个服务的启动耗时
    ○ 重点关注 SystemServer 主线程的 initstart 阶段
  2. 并行化启动服务
    主线程优化 :将不依赖其他服务的系统服务(如 TelephonyRegistry)的启动,从 SystemServer 的主线程移动到单独的线程中,使用 SystemServiceManager.startBootPhase() 来协调启动顺序
    使用 ConcurrentyFramework :在 SystemServer 中利用 ExecutorService 创建线程池,并发启动多个服务
  3. 延迟启动与非关键服务
    识别关键路径 :明确启动 Launcher 所必须 的系统服务(如 ActivityManagerService, PackageManagerService)。其他服务(如 BluetoothService, WiFiService)可以延迟加载
    使用 StartControllersBackgroundLaunch:将非关键服务标记为可以在后台启动,或者等到第一次被绑定时才初始化
  4. 缓存与预加载
    PackageManager 优化PackageManagerService 的扫描和解析是耗时大户
    使用编译时信息 :启用 dex2oatspeed 模式,在系统编译时对系统应用进行预优化
    优化扫描路径 :确保只扫描必要的目录(/system, /vendor, /product),避免扫描 data 分区
    使用 apexmodule:新的模块化分发方式可以减少 PMS 的扫描负担
阶段 四:应用与 Launcher 优化
  1. Launcher 自身优化
    ○ 将 Launcher 视为一个普通应用,应用所有应用启动优化手段
    避免冷启动:确保 Launcher 进程在开机前已被 Zygote 预加载
  2. 系统应用预加载
    ○ 使用 cmd package compile -m speed -f <package-name> 命令在首次启动后或工厂烧录时,预编译关键系统应用为最优的机器码

三. 分析与测量工具

没有测量就无法优化。以下是关键工具:

  1. bootchart
    功能 :生成整个启动过程的 CPU、I/O、进程树的时间线图。是启动优化的首选宏观分析工具
    使用 :在 AOSP 源码中启用 ENABLE_BOOTCHART=true,编译后刷机。开机后会在 /data/bootchart 生成日志,用 pybootchart.py 解析生成图表
  2. systrace / perfetto
    功能 :提供更细粒度的性能分析,可以跟踪系统调用、CPU 调度、锁竞争等。Perfetto 是 Systrace 的升级版
    使用 :在代码中插入 Trace.beginSection("MyService.init")Trace.endSection() 来标记关键代码块。然后使用 python systrace.py 或 Perfetto UI 抓取 trace 文件进行分析
  3. 内核日志
    功能 :通过 dmesg 查看内核启动日志,里面包含了每个驱动初始化的精确时间戳(通过 printk 输出)
    使用adb shell dmesg > dmesg.log,然后分析时间戳间隔较大的部分
  4. Logcat
    功能 :查看系统服务的启动日志。SystemServer 会打印类似 StartService ...Service ... started 的日志
    使用adb logcat -b all -v time -d > logcat.txt,然后搜索 SystemServerActivityManager 的相关日志
  5. 自定义打点
    ○ 在 SystemServer.java 等关键位置添加 logcatSlog.i 输出时间戳,可以非常精确地测量特定服务的启动耗时

四. 实战流程建议

  1. 建立基线 :使用 bootchartsystrace 抓取一次未优化的启动过程,确定总启动时间和各阶段耗时
  2. 定位瓶颈:分析图表,找到耗时最长的阶段(是 Kernel?PMS?还是某个系统服务?)
  3. 制定策略
    ○ 如果是 I/O 密集型(如 PMS 扫描),考虑缓存、预加载、并行扫描
    ○ 如果是 CPU 密集型(如服务初始化逻辑),考虑延迟加载、异步初始化、算法优化
    ○ 如果是等待依赖,考虑调整启动顺序或并行化
  4. 实施修改 :修改 AOSP 代码(如 SystemServer.java, init.rc),每次只做一个修改
  5. 验证效果:重新编译刷机,再次测量,对比优化前后的数据
  6. 迭代:重复步骤 2-5,直到达到目标

总结

层面 关键优化手段
内核/Init 驱动裁剪与延迟初始化,init.rc 任务并行化
Zygote 精简预加载类和资源
SystemServer 服务启动并行化,非关键服务延迟加载,PMS 扫描优化
应用/Launcher 预编译,应用启动优化
工具 bootchart(宏观),systrace/perfetto(微观),logcat/dmesg(日志)
相关推荐
用户41659673693554 小时前
深入理解:SQLite 参数限制、Android 版本与 Room 的兼容性奥秘
android
不知名的前端专家5 小时前
uniapp安卓原生插件实现开启ble Server[外围模式]
android·uni-app·蓝牙
ajassi20005 小时前
开源 java android app 开发(十四)自定义绘图控件--波形图
android·java·开源
Arenaschi9 小时前
Android
android·linux·运维·笔记·其他·docker
2501_9159184111 小时前
HTTPS 请求抓包实战,从请求捕获到解密分析的逐步流程与工具组合(https 请求抓包、iOS 真机、SSL Pinning 排查)
android·ios·小程序·https·uni-app·iphone·ssl
草字11 小时前
uniapp 打包安卓apk。同时安装正式和测试的apk。
android·uni-app
不当菜虚困15 小时前
Android如何自动弹出软键盘?
android
Digitally17 小时前
从安卓手机切换到iPhone:好处、缺点及4种方法
android·智能手机·iphone