【Android】性能优化-开机优化
前言
Android 的性能优化,通常是基于对比机的横向对比,在对比下的数据情况较为糟糕时考虑进行性能优化。Android 的性能优化,大体可以分为开机启动优化和应用启动优化两种类型。
分析步骤
- 分析对比机的硬件条件:cpu;内存;内存硬件品牌等;
- 在产品与对比机的硬件条件相同或相近的情况下:分析软件层面待优化的内容。
开机的关键路径
很多进程都是在设备启动期间进行启动,但只有以下关键路径中的组件才会直接影响启动时间。
- Bootloader
- Kernel
- Init进程(pid为1)
- Zygote进程
- SystemServer
- Launcher
正文
在刷机后,第一次开机启动时,需要初始化加载很多内容,因此往往第一次设备启动的时间会较为耗时。在第一次开机启动时,执行以下命令,抓取系统日志:
//抓取日志后,搜索关键字:boot_process、sf_stop_bootanim、wm_boot_animation_done
adb bugreport
//也可以直接通过以下命令抓取,Windows 系统就把 grep 换成 findstr
adb logcat -b events | grep -E "boot_process|sf_stop_bootanim|wm_boot_animation_done"
//如果是想进一步分析 Kernel 的日志,可以用以下命令抓取日志
adb shell dmesg > dmesg.txt
日志分析:
//时间单位:ms
//boot_process_start 表示 kernel 已经启动完成,也就是 Bootloader -> Kernel 的过程花费的时间为 ms
//boot_process_preload_start 和 boot_process_preload_end 分别表示 Zygote 进程启动开始和启动结束
//boot_process_system_run 表示 SystemServer 启动
//boot_process_pms_start 表示 PMS 启动
//boot_process_pms_system_scan_start 表示 PMS 扫描 /System 目录下的内容
//boot_process_pms_data_scan_start 表示 PMS 扫描 /data 目录下的内容,这个通常较快,因为三方应用一般预置得较少
//boot_process_pms_scan_end 表示 PMS 扫描完成
//boot_process_pms_ready 表示 PMS 进入就绪状态
//boot_process_ams_ready 表示 AMS 进入就绪状态
//boot_process_enable_screen 表示屏幕真正被启用,准备显示开机动画或锁屏界面
//sf_stop_bootanim 表示 Surfaceflinger 中开机动画结束的时间
//wm_boot_animation_done 表示开机动画结束的时间,通常和 sf_stop_bootanim 是同一时刻打印
在 SystemServer 启动后,SystemServer 会在 startBootstrapServices() 方法中,拉起 PMS 和 AMS。其中,最耗时的便是 PMS 去扫描、解析与安装系统预安装的应用,那么 PMS 就是需要着重考虑进行优化的点。
PMS 优化方案
方案一:裁剪应用
找出自己不需要的应用的方法:
- 使用 adb 命令,查看系统已安装的 apk 及其对应的文件路径
adb shell pm list packages -f
// 想要将上述信息保存到一个文件中,可以用此命令替代:adb shell pm list packages -f > 指定路径/pcks.txt
- 打开应用,然后用以下命令查看其包名
adb shell dumpsys window | findstr mCurrentFocus
- 将查看到的包名,拿去到 1. 中查看到的信息,查看 apk 名
- 添加到 PRODUCT_DEL_PACKAGES 中
- 删掉 /out 后重新编译即可
rm -rf ./out
make -j32
具体的修改如下
--- a/build/make/core/product.mk
+++ b/build/make/core/product.mk
@@ -40,6 +40,7 @@ _product_single_value_vars += PRODUCT_AAPT_PREF_CONFIG
_product_list_vars += PRODUCT_AAPT_PREBUILT_DPI
_product_list_vars += PRODUCT_HOST_PACKAGES
_product_list_vars += PRODUCT_PACKAGES
+_product_list_vars += PRODUCT_DEL_PACKAGES
_product_list_vars += PRODUCT_PACKAGES_DEBUG
_product_list_vars += PRODUCT_PACKAGES_DEBUG_ASAN
_product_list_vars += PRODUCT_PACKAGES_ARM64
--- a/build/make/core/main.mk
+++ b/build/make/core/main.mk
@@ -1281,6 +1281,7 @@ define product-installed-files
$(eval ### Filter out the overridden packages and executables before doing expansion) \
$(eval _pif_overrides := $(call module-overrides,$(_pif_modules))) \
$(eval _pif_modules := $(filter-out $(_pif_overrides), $(_pif_modules))) \
+ $(eval _pif_modules := $(filter-out $(PRODUCT_DEL_PACKAGES), $(_pif_modules))) \
$(eval ### Resolve the :32 :64 module name) \
$(eval _pif_modules := $(sort $(call resolve-bitness-for-modules,TARGET,$(_pif_modules)))) \
$(call expand-required-modules,_pif_modules,$(_pif_modules),$(_pif_overrides)) \
最后,在 device/xxx/xxx.mk 配置需要裁剪的应用
--- a/device/qcom/qssi/qssi.mk
+++ b/device/qcom/qssi/qssi.mk
@@ -308,3 +308,33 @@ $(call inherit-product-if-exists, vendor/qcom/defs/product-defs/system/*.mk)
+PRODUCT_DEL_PACKAGES := BTTestApp \
+ Browser2 \
+ BasicDreams \
+ Cam2test \
+ ConnectionManagerTestApp \
+ Calendar \
+ CalendarProvider \
+ Contacts \
+ DeskClock \
+ DCFNearbyClientApp \
+ DocumentsUI \
+ Email \
+ Exchange2 \
+ FM2 \
+ MSDC_UI \
+ Mms \
+ MmsService \
+ MusicFX \
+ ODLT \
+ PresenceApp \
+ QuickSearchBox \
+ QFPCalibration \
+ QSensorTest \
+ QtiTelephonySettings \
+ QtiSoundRecorder \
+ SampleLocationAttribution \
+ SnapdragonMusic \
+ UnifiedSensorTestApp \
+ VoiceAIRef \
方案二:裁剪 feature
方案三:odex 优化
简介:dexopt(dex优化)是指在安装应用或系统启动时,系统将通用的 dex 文件优化为效率更高的 odex 文件,一般是生成 oat 文件,目的是提升应用运行的性能,缺点是会牺牲一些编译时间,而且产生的镜像文件也会大一些,属于空间换时间。
注:现在较高的 Android 版本(比如:Android 14、Android 15等都是默认开启 odex 优化的)
| 配置项 | 含义 | 优先级 |
|---|---|---|
| WITH_DEXPREOPT := true | 启用全局 dex 预优化 | 低 |
| DISABLE_DEXPREOPT := true | 强制禁用 Dex 预优化 | 高 |
| DISABLE_DEXPREOPT := false | 不禁用(通常与 WITH_DEXPREOPT 配合) | 中 |
代码路径:device/qcom/qssi/BoardConfig.mk
# Enable dex pre-opt to speed up initial boot
ifeq ($(HOST_OS),linux)
ifeq ($(WITH_DEXPREOPT),)
DISABLE_DEXPREOPT := false
WITH_DEXPREOPT := true
WITH_DEXPREOPT_PIC := true
ifneq ($(TARGET_BUILD_VARIANT),user)
# Retain classes.dex in APK's for non-user builds
DEX_PREOPT_DEFAULT := nostripping
endif
endif
endif
如果不想开启 odex 优化(比如只是想编译出来验证修改点,可以这么修改缩短编译时间),可以将上述代码修改为:
ifeq ($(HOST_OS),linux)
ifeq ($(WITH_DEXPREOPT),)
# 修改以下代码
DISABLE_DEXPREOPT := true
WITH_DEXPREOPT := false
WITH_DEXPREOPT_PIC := false
# 修改以上代码
ifneq ($(TARGET_BUILD_VARIANT),user)
# Retain classes.dex in APK's for non-user builds
DEX_PREOPT_DEFAULT := nostripping
endif
endif
endif
如果不想对某个 apk 进行 odex 优化,可以对那个 apk 的 mk 文件作出如下修改:
LOCAL_DEX_PREOPT := false
浙公网安备 33010602011771号