一:Android开机流程
开机时间过长会使用户体验很差,所以优化开机时间是项很关键的工作。想优化开机时间,了解清楚开机流程是很有必要的,下图为比较简洁的开机流程图。
1. BootLoader识别到开机事件进行开机,初始化一些外设,播放logo
2. kernel加载硬件有关的驱动,启动userspace第一个进程-init进程
3. init进程解析init.rc文件,创建、挂载分区,启动zygote进程
4. zygote进程启动systemserver,fork其他进程
5. systemserver启动系统服务、核心服务、其他服务,包括AMS、PMS、WMS等
6. Launcher启动
本文旨在优化Android启动的过程,对bootloader、kernel等部分暂不涉及。
二:开机日志的获取
使用user版本,抓取mtklog或者adb logcat -b all > boot.txt抓取开机日志。
三:开机日志的分析
如果是mtklog,在event log中搜索boot_progress。如果是adb抓取的logcat,同样在boot.txt文件中搜索boot_progress。每行最后的数字代表该阶段的耗时,单位是毫秒。
08-24 20:42:57.811 810 810 I boot_progress_start: 6082
08-24 20:42:58.854 810 810 I boot_progress_preload_start: 7125
08-24 20:42:59.966 810 810 I boot_progress_preload_end: 8237
08-24 20:43:00.587 1385 1385 I boot_progress_system_run: 8858
08-24 20:43:01.368 1385 1385 I boot_progress_pms_start: 9639
08-24 20:43:01.500 1385 1385 I boot_progress_pms_system_scan_start: 9771
08-24 20:43:01.861 1385 1385 I boot_progress_pms_data_scan_start: 10132
08-24 20:43:01.864 1385 1385 I boot_progress_pms_scan_end: 10134
08-24 20:43:01.965 1385 1385 I boot_progress_pms_ready: 10236
08-24 20:43:03.161 1385 1385 I boot_progress_ams_ready: 11432
08-24 20:43:04.100 1385 1497 I boot_progress_enable_screen: 12371
08-24 20:43:05.542 1385 1497 I wm_boot_animation_done: 13813
boot_progress解读
阶段 | 描述 |
boot_progress_start | kernel启动完成,系统进入userspace |
boot_progress_preload_start | zygote启动 |
boot_progress_preload_end | zygote结束 |
boot_progress_system_run | systemserver开始启动系统服务 |
boot_progress_pms_start | PMS开始扫描安装的应用 |
boot_progress_pms_system_scan_start | PMS开始扫描system分区下应用 |
boot_progress_pms_data_scan_start | PMS开始扫描data分区下应用 |
boot_progress_pms_scan_end | PMS扫描结束 |
boot_progress_pms_ready | PMS就绪 |
boot_progress_ams_ready | AMS就绪 |
boot_progress_enable_screen | AMS启动完成,开始激活屏幕 |
sf_stop_bootanim | 系统将要结束开机动画 |
wm_boot_animation_done | 开机动画结束 |
一般和对比机对比,哪个阶段耗时较多,再针对性的分析优化。
四:常规优化措施
4.1 日志中是否有大量avc: denied,如果有则添加相应的selinux权限。
4.2 日志中是否有大量[kworke]打印,如果有则修改kernel log level
4.2.1 mtk项目
device/mediatek/mt*/init.mt*.rc文件中添加
on property:ro.build.type=user
write /proc/sys/kernel/printk "1 4 1 7"
4.2.2 高通项目
device/qcom/common/rootdir/etc/init.qcom.sh文件中修改
buildvariant=`getprop ro.build.type`
case "$buildvariant" in
"userdebug" | "eng")
#set default loglevel to KERN_INFO
echo "4 6 1 7" > /proc/sys/kernel/printk
;;
*)
#set default loglevel to KERN_WARNING
- echo "4 4 1 4" > /proc/sys/kernel/printk
+ echo "1 4 1 4" > /proc/sys/kernel/printk
;;
4.3 dex2oat优化耗时
系统第一次开机,会对应用做dex优化,体现在日志里就是boot_progress_ams_ready的时间很长,继续搜索dex2oat32: dex2oat took,可以看到是哪些应用做dex优化耗时较久。
解决方案:
1) 裁剪应用,减少预置应用数量;
2) 在编译时做dex优化,用空间换时间。在build/make/core/dex_preopt.mk文件中添加
DONT_DEXPREOPT_PREBUILTS := false
3) 搜索如下日志,看应用dex2oat是32还是64位指令集。out=/data/dalvik-cache/arm64 代表是64位的,out=/data/dalvik-cache/arm 代表是32位的。
installd: Running /apex/com.android.art/bin/dex2oat32 in=YouTube.apk out=/data/dalvik-cache/arm64/product@app@YouTube@YouTube.apk@classes.dex
对于64bit的芯片,若apk只有32bit的lib或者只能作为32bit运行,请在预置apk时在android.mk中添加下边的TAG标记此apk为32bit:LOCAL_MULTILIB :=32;开机之后既提取arm又提取arm64的apk,请设定LOCAL_MULTILIB :=both
4) check 系统Service的启动时间,看是否有耗时较多的,针对性的处理
5) 开机过程提频,利用的ppm机制。 在device下面项目对应的init.project.rc文件中增加如下修改
on early-init
...
+ write /proc/ppm/policy/ut_fix_core_num 4
+ write /proc/ppm/policy/ut_fix_freq_idx 0
on property:sys.boot_completed=1
...
+ write /proc/ppm/policy/ut_fix_core_num -1
+ write /proc/ppm/policy/ut_fix_freq_idx -1
4.4 开机动画
如果boot_progress_ams_ready时间差不多,wm_boot_animation_done耗时较久,大概率动画资源问题,可尝试减少开机动画张数看是否有优化。
4.5 精简servcies
减少系统服务的数量,非必要服务直接裁剪或者延后启动
4.6 精简apk包
1)删除没有用到的图片、资源文件、jar包、so库
2)自研APP,如果设备只会加载drawable-xhdpi中的资源,在drawable包重复的资源可以直接删除
3)自研APP,如果只有少量语言需求,把不需要的语言资源都删除
4)apk中只保留和系统适配的so文件,比如:armv7和arm64的so文件只保留一个
后续有好的措施会持续更新