前言
在實際應用場景中,特定領域對 Android 系統的啟動時間有著極為嚴苛的要求,車載領域便是典型代表。想象一下,當車輛已經行駛出數公里之遙,車內的信息娛樂系統(IVI)卻仍未完成啟動,這無疑會給用戶帶來極大的不便與尷尬體驗。因此,對 Android 啟動時間進行優化,成為了一項極具重要性與緊迫性的工作。
本文將緊密結合筆者在相關領域的實際工作經驗,深入且詳盡地闡述與 Android 開機時間相關的各項內容。需要特別說明的是,本文所涉及的技術探討與案例分析均基于 Android 13 版本展開,旨在為從事相關工作的技術人員提供具有針對性和實用性的參考與指導。
開機時間檢測方法
logcat
當用戶長按電源鍵啟動設備后,需等待系統完成一系列初始化流程,其中包括 adb 進程的啟動。通常,在屏幕出現 “Android” 字樣這一標志性界面后,表明系統已初步完成關鍵啟動階段。此時,可執行以下命令來抓取開機過程中的 logcat 日志,以便后續分析啟動性能及排查潛在問題:
adb logcat -b all > logcat.txt
打開logcat.txt,搜索logcat關鍵字 ”boot_progress“、“sf_stop_bootanim”、“wm_boot_animation_done”
或者直接執行以下命令過濾logcat
adb logcat -b events | grep -E "boot_progress|sf_stop_bootanim|wm_boot_animation_done"
以下是對 Android 系統啟動各階段耗時的詳細分析。通過相關數據監測,我們可以清晰地看到整個開機流程的總耗時情況:此次開機過程共計耗時 23.283 秒。在這段開機時長中,從用戶按下電源鍵(power 鍵)開始,到系統完成關鍵進程 zygote 的啟動,這一階段耗時 7.646 秒。接下來,對各個啟動階段進行具體解釋:
啟動階段 | 說明 |
---|---|
boot_progress_start | Linux kernel啟動到Zygote進程啟動的時間,包含從kernel啟動到Init啟動Zygote的時間 |
boot_progress_preload_start | ART虛擬機啟動耗時/Zygote開始啟動 |
boot_progress_preload_end | 虛擬機資源裝載耗時/Zygote啟動結束 |
boot_progress_system_run | System Server進程啟動耗時 |
boot_progress_pms_start | Android一些在PMS前需要啟動服務的啟動耗時,package scan開始 |
boot_progress_pms_system_scan_start | system目錄開始scan時間點 |
boot_progress_pms_data_scan_start | data目錄開始scan時間點/system目錄掃描耗時 |
boot_progress_pms_scan_end | 掃描結束時間點/data目錄掃描耗時 |
boot_progress_pms_ready | PMS啟動掃描包耗時 |
boot_progress_ams_ready | PMS后的系統服務啟動時間 |
boot_progress_enable_screen | AMS啟動完成后開始激活屏幕 |
sf_stop_bootanim | surfaceflinger結束開機動畫 |
wm_boot_animation_done | 從enable_screen到animation_done包含壁紙和keyguard的繪制時間 |
需要特別留意的是,logcat 日志工具主要用于捕獲和顯示 Android 系統上層(應用層及框架層)運行過程中的日志信息。也就是說,當 zygote 進程成功啟動后,系統進入上層框架及應用的初始化階段,此時通過 logcat 可以記錄并查看這一階段的詳細日志。然而,在開機過程中,kernel 層(內核層)的啟動和初始化發生在 zygote 啟動之前,這一階段的耗時情況無法通過 logcat 直接觀察和分析。kernel 層的啟動涉及硬件驅動加載、內存管理初始化、進程調度機制建立等關鍵操作,其耗時對整體開機性能有著重要影響,但需要借助其他工具或方法來獲取和分析這部分的耗時數據。
串口log和kernel log
- 串口log可以使用串口線連接Android設備和PC,使用串口工具抓取log,常用的串口工具有很多,xshell、MobaXterm等。
- kernel log是在開機后執行如下命令抓取:
adb shell dmesg > dmesg.txt
log里面搜關鍵字 “KPI” 、“first stage” 、“second stage” ,此關鍵字為kernel的各個啟動階段。
uart log和kernel log都可以顯示整個開機過程時間。
左側為啟動時間軸,右側為啟動log。
bootchart
Bootchart 是一款專為 Linux 系統啟動過程性能分析而設計的開源工具軟件。在系統啟動期間,它能夠自動且全面地收集關鍵數據,涵蓋 CPU 占用率、磁盤吞吐率以及進程的詳細信息等。收集完數據后,Bootchart 會以直觀的圖形化方式呈現分析結果。這種可視化展示極大地方便了用戶,使他們無需深入鉆研復雜的底層數據,就能輕松理解系統啟動過程中的各項情況。
借助 Bootchart,用戶可以極為直觀地查看系統啟動的完整流程,以及每個具體階段所耗費的時間。基于這些清晰呈現的信息,用戶能夠深入剖析啟動過程中的各個環節,精準定位可能存在的性能瓶頸或低效環節。進而,用戶可以依據分析結果,有針對性地對系統啟動過程進行優化,有效減少不必要的耗時操作,最終達到提高系統啟動時間的目的。
- 安裝bootchart
Ubuntu16.04和18.04可通過一下命令安裝
sudo apt-get install bootchart
sudo apt-get install pybootchartgui
Ubuntu20.04上無法定位pybootchartgui
這時可以手動下載,然后放到python編譯器搜尋的目錄下。
下載地址:github.com/xrmx/bootchart/releases
下載好后解壓
tar -zxvf bootchart-0.14.9.tar.gz
得到目錄bootchart-0.14.9,進入到該目錄
將圖中的pybootchartgui目錄復制到 /usr/lib/python3.8/ 目錄下
sudo cp -r /usr/lib/python3.8/bootchart-0.14.9/pybootchartgui/ /usr/lib/python3.8/
/usr/lib/python3.8/ 是python編譯器搜尋的目錄之一,完整的搜尋目錄列表可通過以下命令查看
python3 -c "import sys;print(sys.path)"
因此,在實際操作中,我們可以將 pybootchartgui 目錄復制到上述任意一個 Python 編譯器能夠搜索到的路徑中。只要確保該目錄在 Python 的模塊搜索路徑范圍內,工具就能被正確調用。
不過,在完成復制操作后,有一個關鍵細節需要特別注意:必須將目錄中的 main.py.in 文件重命名為 main.py。如果忽略這一步驟,運行工具時將會遇到錯誤提示。這一問題已在 GitHub 的 相關 issue中被提及和討論,開發者可以通過查閱該 issue 了解更詳細的問題背景和解決方案。重命名文件后,工具即可正常運行,為系統啟動性能分析提供有力支持。
重命名命令
sudo mv /usr/lib/python3.8/pybootchartgui/main.py.in /usr/lib/python3.8/pybootchartgui/main.py
最后,我們需要將 bootchart 和 pybootchartgui 這兩個文件復制到系統的 /usr/bin/ 目錄下(相關文件可參考文末說明)。值得注意的是,這兩個文件實際上是等效的,即它們具備相同的功能。這意味著,無論你是通過執行 bootchart 命令,還是 pybootchartgui 命令,最終都能成功生成 bootchart.png 這一可視化圖表,用于分析系統啟動過程。這樣的設計為用戶提供了更多的操作靈活性,方便根據個人習慣或實際需求選擇合適的命令來執行任務。
生成bootchart.png開機圖
- 準備userdebug或者userroot設備
- 開啟bootchart
adb root
adb shell
touch /data/bootchart/ enabled
- 檢查是否生成了enabled
# ls /data/bootchart/
enabled
- 重啟設備
adb reboot
- 等待開機進入Launcher,查看 /data/bootchart/ 下是否有生成header文件,即bootchart日志是否生成
adb root
adb shell
ls /data/bootchart/
- 拷貝 /data/bootchart/ 下的 4 個文件到本地
proc_diskstats.log
proc_ps.log
proc_stat.log
header# Pull指令:
adb pull /data/bootchart/
- 進入到 bootchart 目錄(剛剛 pull 的文件夾),執行指令將這 4 個文件打包起來(在 bootchart 目錄中打開終端)
tar -czf bootchart.tgz *
- 執行指令,生成 bootchart.png 文件(./指代當前目錄)
bootchart ./ bootchart.tgz
- 拷貝 bootchart.png 到你需要的地方,雙擊查看
bootchart.png示例圖
Bootchart 圖能夠以極為直觀的可視化形式,清晰呈現整個開機過程中各個關鍵時間節點,讓用戶一目了然地了解系統從啟動到完成初始化的各個階段。同時,它還能精準展示 CPU 的使用率波動情況,以及磁盤在不同階段的讀寫負載變化,幫助用戶全面掌握系統啟動期間的資源消耗狀況,為深入分析和優化開機性能提供有力的數據支撐。
- bootchart.png講解
第一行:時間
第二行:Linux版本
第三行:odm release fingerprint
第三行:cpu架構
第四行:kernel配置選項
第五行:開機耗時
開機過程中,CPU的使用率、I/O狀態、磁盤吞吐量、磁盤使用率
第一行:代表整個機器開機的時間,每一格代表1秒
第二行:代表init從長格子開始的位置開始啟動
最后一行:開始zygote的啟動,后面就是java 世界:system_server及app進程
kernel相關的啟動部分,啟動時間看下init什么時候啟動的就知道了。
影響開機時間的Android啟動流程
開機框架
引用Gityuan大佬的一張開機流程圖
Android啟動流程大體為:BootRom -> BootLoader -> Kernel -> Init -> Zygote -> SystemServer ->Launcher
Loader層
- Boot ROM
當用戶按下電源鍵后,設備的啟動流程正式開始。此時,引導芯片(Boot ROM)中的固化代碼會被激活,并從預定義的存儲位置(通常是只讀存儲器 ROM)開始執行。這段初始代碼負責完成最基本的硬件初始化工作,例如對 CPU、內存控制器等關鍵硬件進行自檢和配置。隨后,引導芯片會將存儲設備中的引導程序(Bootloader)加載到系統內存(RAM)中,并跳轉到該程序的入口點以執行后續操作。這一階段是系統啟動的基石,確保了硬件環境能夠正確支持后續操作系統的加載與運行。
- Boot Loader
此引導程序處于 Android 系統啟動流程的前期階段,承擔著至關重要的基礎初始化任務。它首先會對外部 RAM 進行全面檢測,確保內存硬件能夠正常工作且滿足系統后續運行的容量需求。在此基礎上,該引導程序會進一步執行網絡參數配置、內存管理策略設置以及各類硬件參數的初始化工作,為 Android 操作系統的加載與穩定運行構建起可靠的硬件環境基礎。
Kernel層
Kernel層是指Android內核層,到這里才剛剛開始進入Android系統。
- 啟動swapper進程(pid=0),該進程又稱為idle進程,,系統初始化過程Kernel由無到有開創的第一個進程,,用于初始化進程管理、內存管理,加載Display、Camera Driver、Binder Driver等相關工作(圖中kernel層藍色區塊)。
- 啟動kthreadd進程(pid=2),是Linux系統的內核進程,會創建內核工作線程kworkder,軟中斷線程ksoftirqd,thermal等一系列內核守護進程。kthreadd進程是所有內核進程的父進程。
Linux內核加載主要包括初始化kernel核心(內存初始化,打開中斷,初始化進程表等)、初始化驅動、啟動內核后臺(daemons)線程、安裝根(root)文件系統等。后續啟動第一個用戶級進程init(pid=1)。
Native層
Native層主要包括啟動init進程(Android的第一個用戶空間進程)、HAL層(硬件抽象層)以及開機動畫等。init進程是所有用戶進程的鼻祖。同時init進程也會孵化一系列用戶進程,還會啟動關鍵的服務以及孵化Zygote進程。
- init進程會孵化出ueventd、logd、healthd、installd、adbd、lmkd等用戶守護進程。
- init進程還啟動servicemanager(binder服務管家)、bootanim(開機動畫)等重要服務。
- init進程孵化出Zygote進程,Zygote進程是Android系統的第一個Java進程,Zygote是所有Java進程的父進程,Zygote進程本身是由init進程孵化而來的。
Framework層
Framework層分為Java frameword和C++ framework,分別由system_server進程和media_server進程負責啟動和管理。
zygote本身是一個native的應用程序,剛開始的名字為“app_process”,運行過程中,通過系統調用將自己名字改為zygote。在上圖中的紅色線,便是zygote fork出來的進程,所有的app進程都是由zygote fork產生的。
下面列舉Zygote進程孵化的部分子進程:
進程名 | 解釋 |
---|---|
system_server | Java framework的各種service都依賴此進程 |
com.android.phone | 電話應用進程 |
android.process.acore | 通訊錄進程 |
android.process.media | 多媒體應用進程 |
com.android.settings | 設置進程 |
com.android.wifi | wifi應用進程 |
- zygote進程
由init進程通過解析init.rc文件后fork生成的,Zygote進程主要包含:
- 加載ZygoteInit類,注冊Zygote Socket服務端套接字
- 加載虛擬機
- preloadClasses
- preloadResouces
- system_server進程
由zygote進程fork而來,system_server是zygote孵化的第一個進程,system_server負責啟動和管理整個java framework,包含ActivityManager、PowerManager等服務。
- media_server進程
由init進程fork而來,負責啟動和管理整個C++ framework,包含SurfaceFlinger、AudioFlinger、Camera Service等服務。
app層
- zygote進程孵化出的第一個app進程是Launcher,這是用戶看到的桌面app。
- zygote進程還會創建Browser,Phone,Email等app進程,每個app至少運行在一個進程上。
- 所有的app進程都是由zygote進程fork生成的。
具體的啟動過程,此文不便詳述,都是代碼分析,復雜且枯燥。
開機時間優化方案
以下均為framework層的優化,kernel層優化不在研究范圍。
精簡方向
精簡初始化腳本:減少開機時的初始化時間。
高通平臺關注以下.rc & .sh文件:
init.rc
init.target.rc
init.qcom.rc
init.sh
init.qcom.sh
init.qcom.post_boot.sh
裁剪方向
移除非必須Apks、Features、Sensor等,減少PackageScan時間。
針對具體應用場景,可以將沒用的apk裁剪掉,比如automotive可以裁掉Launcher,因為automotive自帶CarLauncher。
可通過如下命令查看設備中所有的apk:
adb shell pm list package -f
Android中的內置APK介紹見:Android主要應用和進程說明
裁剪方法:
diff --git /build/make/core/main.mk /build/make/core/main.mk
index a8f46c1..d9d507b 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -1267,6 +1267,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 $(modules_product_packages_remove), $(_pif_modules))) \$(eval _pif_modules := $(filter-out $(PRODUCT_PACKAGES_DEL), $(_pif_modules))) \$(eval ### Resolve the :32 :64 module name) \$(eval _pif_modules := $(sort $(call resolve-bitness-for-modules,TARGET,$(_pif_modules)))) \
@@ -1363,6 +1364,9 @@ else ifdef FULL_BUILDendifendif+ # App removal list
+ modules_product_packages_remove := $(PRODUCT_PACKAGES_REMOVE)
diff --git /build/make/core/product.mk /build/make/core/product.mk
index 90e960b..c556037 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -40,6 +40,9 @@ _product_list_vars += PRODUCT_PACKAGES_ENG_product_list_vars += PRODUCT_PACKAGES_TESTS_product_var_list += PRODUCT_PACKAGES_DEL+# App removal list
+_product_list_vars+= PRODUCT_PACKAGES_REMOVE
+# The device that this product maps to._product_single_value_vars += PRODUCT_DEVICE_product_single_value_vars += PRODUCT_MANUFACTURER
diff --git /device/qcom/{product}/{product}.mk /device/qcom/{product}/{product}.mk
index 163cac2..89a3078 100755
--- a/{product}.mk
+++ b/{product}.mk
@@ -60,6 +60,8 @@ PRODUCT_BUILD_USERDATA_IMAGE := true
+# App removal list
+PRODUCT_PACKAGES_REMOVE += \
+ Calendar \
+ Email \
+ SnapdragonMusic \
+ DeskClock \
注意: /device/qcom/{product}/{product}.mk 取決于廠商的產品名稱
針對具體應用場景,可以將沒用的Features裁剪掉,比如automotive可以裁掉
可通過如下命令查看設備中所有的Features:
adb shell pm list features
裁剪方法:
diff --git /frameworks/native/data/etc/android.software.print.xml /frameworks/native/data/etc/android.software.print.xml
index 713a7f7..e76bb88 100644
--- /frameworks/native/data/etc/android.software.print.xml
+++ /frameworks/native/data/etc/android.software.print.xml
@@ -15,5 +15,5 @@--><permissions>
- <feature name="android.software.print" />
+<!-- <feature name="android.software.print" />--></permissions>
針對具體應用場景,可以將沒用的Sensor裁剪掉。
可通過如下命令查看設備中所有支持的Sensor:
adb shell dumpsys sensorservice
配置優化方向
PinnerService是用于鎖定某些模塊在內存中,避免這些模塊被移出\移入內存從而提高程序的運行效率。優化目的是減少非首次開機啟動Service的時間。
修改 /frameworks/base/core/res/res/values/config.xml ,添加如下配置:
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
... ...<!-- Default files to pin via Pinner Service --><string-array translatable="false" name="config_defaultPinnerServiceFiles"><item>"/system/framework/arm/boot-framework.art"</item><item>"/system/lib/libjavacrypto.so"</item><item>"/system/lib/libhidltransport.so"</item><item>"/system/framework/arm/boot-core-libart.oat"</item><item>"/system/framework/arm/boot-conscrypt.oat"</item><item>"/system/framework/arm/boot-core-libart.art"</item><item>"/system/framework/arm/boot-ext.art"</item><item>"/system/framework/arm/boot.art"</item><item>"/system/framework/arm/boot-framework.art"</item></string-array>
... ...</resources>
注意:芯片商(例如高通)的代碼可能會存在客制化,AOSP的位置可能會被覆蓋,如果有,則以芯片商的代碼為準。
定義了32Bit的程序,機器在apk的使用及服務的申明都會有略微的精簡,在設備啟動時加載的資源會少,故加載時間會少。
修改方式:
/device/qcom/{product}/BoardConfig.mk
TARGET_ARCH := arm
TARGET_ARCH_VARIANT := armv8-2a
TARGET_CPU_ABI := armeabi-v7a
TARGET_CPU_ABI2 := armeabi
TARGET_CPU_VARIANT := cortex-a9#TARGET_2ND_ARCH := arm
#TARGET_2ND_ARCH_VARIANT := armv8-2a
#TARGET_2ND_CPU_ABI := armeabi-v7a
#TARGET_2ND_CPU_ABI2 := armeabi
#TARGET_2ND_CPU_VARIANT := cortex-a9
device/generic/art/armv8/armv8.mk
# Force 32bits executables.
PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.zygote=zygote32
默認關閉功能開關,開機期間不再自動啟動,加快開機進度。
主要修改 /frameworks/base/packages/SettingsProvider/res/values/defaults.xml
- 1.關閉鎖屏顯示通知
<!-- Default for Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1==on -->
- <integer name="def_lock_screen_show_notifications">1</integer>
+ <integer name="def_lock_screen_show_notifications">0</integer>
- 2.關閉手勢喚醒
<!-- Default for Settings.Secure.WAKE_GESTURE_ENABLED -->
- <bool name="def_wake_gesture_enabled">true</bool>
+ <bool name="def_wake_gesture_enabled">false</bool>
- 3.關閉雙擊喚醒
<!-- Default state of tap to wake -->
- <bool name="def_double_tap_to_wake">true</bool>
+ <bool name="def_double_tap_to_wake">false</bool>
- 4.關閉充電振動
<!-- Default for Settings.Secure.CHARGING_VIBRATION_ENABLED -->
- <bool name="def_charging_vibration_enabled">true</bool>
+ <bool name="def_charging_vibration_enabled">false</bool>
- 5.關閉充電提示音
<!-- Default for Settings.Secure.CHARGING_SOUNDS_ENABLED -->
- <bool name="def_charging_sounds_enabled">true</bool>
+ <bool name="def_charging_sounds_enabled">false</bool>
- 6.關閉藍牙和wifi
<bool name="def_bluetooth_on">false</bool>
<bool name="def_wifi_display_on">false</bool>
- 7.關閉自動旋轉
<bool name="def_accelerometer_rotation">false</bool>
- 8.關閉Wifi Debugging
<!-- Disable WiFi Debugging -->
<bool translatable="false" name="config_wifi_enable_wifi_firmware_debugging">false</bool>
Animation的資源大小和播放時長一直是影響開機時間的重要因素之一,移除開機動畫將有效地加快開機速度。
frameworks/base/cmds/bootanimation/BootAnimationUtil.cpp
bool bootAnimationDisabled() {char value[PROPERTY_VALUE_MAX];//將獲取結果改為1,則無法進入到開機動畫流程中//property_get("debug.sf.nobootanimation", value, "0");property_get("debug.sf.nobootanimation", value, "1");if (atoi(value) > 0) {return true;}property_get("ro.boot.quiescent", value, "0");if (atoi(value) > 0) {// Only show the bootanimation for quiescent boots if this system property is set to enabledif (!property_get_bool("ro.bootanim.quiescent.enabled", false)) {return true;}}return false;
}
開機過程中讓CPU火力全開,能有效減少開機時間
/device/qcom/common/rootdir/etc/init.qcom.rc
on early-init
+ write /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor performance
+ write /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor performance
+ write /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor performance
+ write /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor performance
+ write /sys/devices/system/cpu/cpu4/cpufreq/scaling_governor performance
+ write /sys/devices/system/cpu/cpu5/cpufreq/scaling_governor performance
+ write /sys/devices/system/cpu/cpu6/cpufreq/scaling_governor performance
+ write /sys/devices/system/cpu/cpu7/cpufreq/scaling_governor performance
注意:
- init.qcom.rc是高通定制的init腳本,是開機時必然執行的。
- 如果CPU原本就已經滿載了,那么此修改則無效果。
- 不同平臺CPU的配置不盡相同。
SystemServer進程啟動后,會啟動很多SystemService,根據實際場景,裁剪非必要的Service
frameworks/base/services/java/com/android/server/SystemServer.java
// Start services.
try {t.traceBegin("StartServices");startBootstrapServices(t);startCoreServices(t);startOtherServices(t);startApexServices(t);
} catch (Throwable ex) {Slog.e("System", "******************************************");Slog.e("System", "************ Failure starting system services", ex);throw ex;
} finally {t.traceEnd(); // StartServices
}
可裁剪的Service如下,僅供參考
1.VibratorService 震動器服務
2.ClipboardService 粘貼板服務
3.FingerprintService 指紋 4.BatteryService 電池服務,當電量不足時發廣播
5.AlarmManagerService 鬧鐘服務
6.WallpaperManagerService 壁紙管理服務
7.StatusBarManagerService 狀態欄管理服務
注意:
- 從framework層的角度去看問題,我們會發現功能及服務的裁剪,是最直接、最有效地時間及空間優化方法,它可以做到時間與空間的兩者兼顧。
- 注意app與Service,Service與Service之間的耦合性,避免引起機器的異常,無法開機;
修改下面文件中的 PRODUCT_PACKAGES 字段的內容,將不需要的內置應用的名稱刪除,這樣可以縮短 scan packages 的過程。
1.build/target/product/core.mk
2.build/target/product/full_base.mk
3.build/target/product/full_base_telephony.mk
4.build/target/product/generic_no_telephony.mk
同時,可以刪除 /packages/apps/ 路徑下不必要的 app 源碼,這樣可以縮短編譯時間。
apk odex優化就是以空間換時間,加快apk啟動速度,缺點是會消耗內存。
在 /device/qcom/{product}/{product}.mk 加入 WITH_DEXPREOPT=true , 打開odex優化
Android.bp中添加
android_app {dex_preopt: {enabled: true,},
}
Android.mk中添加
LOCAL_DEX_PREOPT := true
Apk的掃描安裝耗時是大頭。通常采用多線程方案,針對Dir或者Dir中的package進行多線程掃描.
PMS多線程掃描apk,4線程改成8線程,注意,如果客戶做了CPU綁核, Android所分配的CPU資源受到限制,導致改成8線程之后反向優化了。
frameworks/base/services/core/java/com/android/server/pm/ParallelPackageParser.java
class ParallelPackageParser {private static final int QUEUE_CAPACITY = 30;
// private static final int MAX_THREADS = 4;private static final int MAX_THREADS = 8;//省略部分代碼
}
Zygote主要是優化class和resource的預加載,可以減少部分不需要預加載的class和resource,具體優化哪些,根據實際需求來添加。
注意:并不是預加載越少越好,如果開機必須啟動的進程所需要的class和resource在zygote階段被優化了,那么也會在該進程自啟動時也會去加載,這樣優化就是無效的。
diff --git /frameworks/base/config/preloaded-classes /frameworks/base/config/preloaded-classes
index f2530519247..d6ac1e22e3f 100644
--- /frameworks/base/config/preloaded-classes
+++ /frameworks/base/config/preloaded-classes
@@ -806,7 +806,6 @@ android.app.VoiceInteractor$Requestandroid.app.VoiceInteractorandroid.app.Vr2dDisplayProperties$1android.app.Vr2dDisplayProperties
-android.app.VrManagerandroid.app.WaitResult$1android.app.WaitResultandroid.app.WallpaperColors$1
@@ -2471,12 +2470,6 @@ android.hardware.display.Time$1android.hardware.display.Timeandroid.hardware.display.VirtualDisplayConfig$1android.hardware.display.VirtualDisplayConfig
-android.hardware.display.WifiDisplay$1
-android.hardware.display.WifiDisplay
-android.hardware.display.WifiDisplaySessionInfo$1
-android.hardware.display.WifiDisplaySessionInfo
-android.hardware.display.WifiDisplayStatus$1
-android.hardware.display.WifiDisplayStatusandroid.hardware.face.Face$1android.hardware.face.Faceandroid.hardware.face.FaceManager$1
diff --git /frameworks/base/packages/overlays/Android.mk /frameworks/base/packages/overlays/Android.mk
index 69641e69a9f..71f5fd00520 100644
--- /frameworks/base/packages/overlays/Android.mk
+++ /frameworks/base/packages/overlays/Android.mk
@@ -20,17 +20,8 @@ LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0LOCAL_LICENSE_CONDITIONS := noticeLOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../NOTICELOCAL_REQUIRED_MODULES := \
- DisplayCutoutEmulationCornerOverlay \
- DisplayCutoutEmulationDoubleOverlay \
- DisplayCutoutEmulationHoleOverlay \
- DisplayCutoutEmulationTallOverlay \
- DisplayCutoutEmulationWaterfallOverlay \FontNotoSerifSourceOverlay \NavigationBarMode3ButtonOverlay \
- NavigationBarModeGesturalOverlay \
- NavigationBarModeGesturalOverlayNarrowBack \
- NavigationBarModeGesturalOverlayWideBack \
- NavigationBarModeGesturalOverlayExtraWideBack \preinstalled-packages-platform-overlays.xmlinclude $(BUILD_PHONY_PACKAGE)
frameworks/base/core/res/res/values/config.xml
<!-- True if WallpaperService is enabled -->
<bool name="config_enableWallpaperService">true</bool>
frameworks/base/packages/SettingsProvider/res/values/defaults.xml
- <fraction name="def_window_animation_scale">100%</fraction>
- <fraction name="def_window_transition_scale">100%</fraction>
+ <fraction name="def_window_animation_scale">25%</fraction>
+ <fraction name="def_window_transition_scale">25%</fraction>
如果想關閉animaton,直接將數值改為0即可。
注意:芯片商可能會定制 defaults.xml ,所以在修改時請留意是否改全。
針對實際項目,如果加了自定義的開機自啟動項,那么可以抓trace,看看整個開機過程哪個啟動項耗時較長
例如:
上圖可以看到 avm_worker 存在耗時異常, 該進程為 android 側的 360 環視功能, 可以找對應開發確認是否需要開機啟動。
詳見:source.android.google.cn/docs/core/perf/boot-times?hl=zh-cn
實戰總結
在 Android 開機時間優化中,Framework 層的優化空間有限。通過性能追蹤工具可發現,單個系統服務的啟動或大量 APK 的掃描,通常僅需幾毫秒到幾十毫秒。因此,即便關閉某些服務或裁剪部分 APK,優化效果也僅在毫秒級,難以察覺。不過,通過多種優化措施疊加,仍能累積出可見效果。相比之下,Kernel 層優化空間較大,優化幅度可達秒級。結合底層(Kernel)與上層(Framework)雙向優化,最終可實現顯著的開機提速效果。
bootchart安裝包
鏈接: pan.baidu.com/s/1BKVd348fZV8xkYLj9hfTzA?pwd=253x 提取碼: 253x