Android13 開機時間優化

前言

在實際應用場景中,特定領域對 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_startLinux kernel啟動到Zygote進程啟動的時間,包含從kernel啟動到Init啟動Zygote的時間
boot_progress_preload_startART虛擬機啟動耗時/Zygote開始啟動
boot_progress_preload_end虛擬機資源裝載耗時/Zygote啟動結束
boot_progress_system_runSystem Server進程啟動耗時
boot_progress_pms_startAndroid一些在PMS前需要啟動服務的啟動耗時,package scan開始
boot_progress_pms_system_scan_startsystem目錄開始scan時間點
boot_progress_pms_data_scan_startdata目錄開始scan時間點/system目錄掃描耗時
boot_progress_pms_scan_end掃描結束時間點/data目錄掃描耗時
boot_progress_pms_readyPMS啟動掃描包耗時
boot_progress_ams_readyPMS后的系統服務啟動時間
boot_progress_enable_screenAMS啟動完成后開始激活屏幕
sf_stop_bootanimsurfaceflinger結束開機動畫
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_serverJava framework的各種service都依賴此進程
com.android.phone電話應用進程
android.process.acore通訊錄進程
android.process.media多媒體應用進程
com.android.settings設置進程
com.android.wifiwifi應用進程
  • 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

針對具體應用場景,可以將沒用的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

針對具體應用場景,可以將沒用的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>
  • 禁用不需要的Sensors

針對具體應用場景,可以將沒用的Sensor裁剪掉。
可通過如下命令查看設備中所有支持的Sensor:

adb shell dumpsys sensorservice
配置優化方向
  • 優化PinnerService配置

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程序

定義了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滿載

開機過程中讓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的配置不盡相同。
  • 移除SystemService

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之間的耦合性,避免引起機器的異常,無法開機;
  • 移除app源碼

修改下面文件中的 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 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
  • PMS優化

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優化

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 環視功能, 可以找對應開發確認是否需要開機啟動。

  • Google優化方案

詳見: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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/82520.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/82520.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/82520.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

08SpringBoot高級--自動化配置

目錄 Spring Boot Starter 依賴管理解釋 一、核心概念 二、工作原理 依賴傳遞&#xff1a; 自動配置&#xff1a; 版本管理&#xff1a; 三、核心流程 四、常用 Starter 示例 五、自定義 Starter 步驟 創建配置類&#xff1a; 配置屬性&#xff1a; 注冊自動配置&a…

基于cornerstone3D的dicom影像瀏覽器 第二十四章 顯示方位、坐標系、vr輪廓線

系列文章目錄 文章目錄 系列文章目錄前言一、工具欄修改二、切片窗口顯示方位文字1. 修改mprvr.js&#xff0c;添加函數getOrientationMarkers2. 修改DisplayerArea3D.vue 三、vr窗口顯示坐標系1. 修改mprvr.js 添加OrientationMarkerTool2. view3d.vue中響應工具欄事件3. 修改…

【C/C++】線程局部存儲:原理與應用詳解

文章目錄 1 基礎概念1.1 定義1.2 初始化規則1.3 全局TLS vs 局部靜態TLS 2 內存布局2.1 實現機制2.2 典型內存結構2.3 性能特點 3 使用場景/用途3.1 場景3.2 用途 4 注意事項5 對比其他技術6 示例代碼7 建議7.1 調試7.2 優化 8 學習資料9 總結 在 C 多線程編程中&#xff0c;線…

【圖像大模型】IP-Adapter:圖像提示適配器的技術解析與實踐指南

IP-Adapter&#xff1a;圖像提示適配器的技術解析與實踐指南 一、項目背景與技術價值1.1 圖像生成中的個性化控制需求1.2 IP-Adapter的核心貢獻 二、技術原理深度解析2.1 整體架構設計2.2 圖像特征編碼器2.3 訓練策略 三、項目部署與實戰指南3.1 環境配置3.2 模型下載3.3 基礎生…

MySQL-5.7 修改密碼和連接訪問權限

一、MySQL-5.7 修改密碼和連接權限設置 修改密碼語法 注意&#xff1a;rootlocalhost 和 root192.168.56.% 是兩個不同的用戶。在修改密碼時&#xff0c;兩個用戶的密碼是各自分別保存&#xff0c;如果兩個用戶密碼設置不一樣則登陸時注意登陸密碼 GRANT ALL PRIVILEGES ON …

Linux基本指令篇 —— touch指令

touch是Linux和Unix系統中一個非常基礎但實用的命令&#xff0c;主要用于操作文件的時間戳和創建空文件。下面我將詳細介紹這個命令的用法和功能。 目錄 一、基本功能 1. 創建空文件 2. 同時創建多個文件 3. 創建帶有空格的文件名&#xff08;需要使用引號&#xff09; 二、…

mysql explain使用

文章目錄 type 訪問類型性能高到低多注意type: index 出現的場景 key 實際使用的索引Extra 額外信息其他字段 通過 EXPLAIN 你可以知道&#xff1a;如是否使用索引、掃描多少行、是否需要排序或臨時表 EXPLAIN 三板斧&#xff08;type、key、Extra&#xff09; 例子&#xff1…

JMeter-SSE響應數據自動化

結構圖 背景&#xff1a; 需要寫一個JMeter腳本來進行自動化測試&#xff0c;主要是通過接口調用一些東西&#xff0c;同時要對響應的數據進行處理&#xff0c;包括不限于錯誤信息的輸出。 1.SSE(摘錄) SSE&#xff08;Server-Sent Events&#xff09;是一種基于HTTP協議、允許…

<<運算符重載 和 c_str() 的區別和聯系

例題 文章開始之前我們看下以下代碼&#xff0c;你能精準的說出正確的輸出結果并知道其原理嗎&#xff1f; void test() {string s1("hello world");cout << s1 << endl;//cout << s1.c_str() << endl;//const char* p1 "xxxx"…

python web flask專題-Flask入門指南:從安裝到核心功能詳解

Flask入門指南&#xff1a;從安裝到核心功能詳解 Flask作為Python最流行的輕量級Web框架之一&#xff0c;以其簡潔靈活的特性廣受開發者喜愛。本文將帶你從零開始學習Flask&#xff0c;涵蓋安裝配置、項目結構、應用實例、路由系統以及請求響應處理等核心知識點。 1. Flask安…

一種C# 的SM4 的 加解密的實現,一般用于醫療或者支付

一種C# 的SM4 的 加解密的實現 一般用于醫療或者支付 加密 string cipherText SM4Helper.Encrypt_test(data, key); public static string Encrypt_test(string plainText, string key) { byte[] keyBytes Encoding.ASCII.GetBytes(key); byte[] input…

“軒轅杯“云盾礪劍CTF挑戰賽 Web wp

文章目錄 ezflaskezjsezrceezssrf1.0簽到ezsql1.0ez_web1非預期預期解 ezflask ssti, 過濾了一些關鍵詞, 繞一下就行 name{{url_for["__globals__"]["__builtins__"]["eval"]("__tropmi__"[::-1])(os)["po""pen"…

Matlab快速上手五十六:詳解符號運算里假設的用法,通過假設可以設置符號變量的取值范圍,也可以通過假設設置變量屬于集合:整數、正數和實數等

1.符號變量中假設的概念 在符號數學工具箱中&#xff0c;符號變量默認范圍是全體復數&#xff0c;也就是說&#xff0c;符號運算是在全體復數域進行的&#xff0c;若需要運算中&#xff0c;不使用全體復數域&#xff0c;可以為變量設定取值范圍&#xff0c;這就用到了假設&…

【python實用小腳本-79】[HR轉型]Excel難民到數據工程師|用Python實現CSV秒轉JSON(附HRIS系統對接方案)

場景故事&#xff1a;從手動復制粘貼到自動化數據流轉 "Kelly&#xff0c;我們需要把3000名員工的考勤數據導入新HR系統&#xff0c;今天能完成嗎&#xff1f;"去年這個時候&#xff0c;作為HRIS項目負責人的我&#xff0c;面對這個需求時第一反應是打開Excel開始手…

數據透視:水安 B 證如何影響水利企業的生存指數?

某大數據公司提取了 3000 家水利企業的經營數據&#xff0c;一組關聯分析令人震驚&#xff1a;B 證配備率與企業利潤率的相關系數達 0.67—— 這意味著持證率每提升 10%&#xff0c;企業利潤率平均提高 4.2 個百分點。當我們用數據解剖這本紅本本&#xff0c;會發現它像一根無形…

從零搭建上門做飯平臺:高并發訂單系統設計

你知道為什么聰明人都在搶著做上門做飯平臺嗎&#xff1f;因為這可能是餐飲行業最后一片藍海&#xff01;傳統餐飲還在為房租人工發愁時&#xff0c;上門私廚已經輕裝上陣殺出重圍。不需要門店租金&#xff0c;不用養服務員&#xff0c;廚師直接上門服務&#xff0c;成本直降60…

openpi π? 項目部署運行邏輯(四)——機器人主控程序 main.py — aloha_real

π? 機器人主控腳本都在 examples 中&#xff1a; 可以看到包含了多種類機器人適配 此筆記首先記錄了 aloha_real 部分 aloha_real 中&#xff0c;main.py 是 openpi ALOHA 平臺上“主控執行入口”&#xff0c;負責&#xff1a; 建立與推理服務器&#xff08;serve_policy.…

利用 Python 爬蟲獲取唯品會 VIP 商品詳情:實戰指南

在當今電商競爭激烈的環境中&#xff0c;VIP 商品往往是商家的核心競爭力所在。這些商品不僅代表著品牌的高端形象&#xff0c;更是吸引高價值客戶的關鍵。因此&#xff0c;獲取 VIP 商品的詳細信息對于市場分析、競品研究以及優化自身產品策略至關重要。Python 作為一種強大的…

鴻蒙桌面快捷方式開發

桌面快捷方式開發實戰 [參考文檔] (https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-desktop-shortcuts) 在module.json5配置文件中的abilities標簽下的metadata中設置resource屬性值為$profile:shortcuts_config&#xff0c;指定應用的快捷方式配置文件&…

3分鐘學會跨瀏覽器富文本編輯器開發:精準光標定位+內容插入(附完整代碼)

一、痛點直擊&#xff1a;傳統編輯器的三大坑 作為前端開發&#xff0c;你是否遇到過以下靈魂拷問&#xff1f; ? 為什么Firefox光標能精準定位&#xff0c;IE卻永遠跳轉到開頭&#xff1f;? 圖片上傳后如何保證插入位置不偏移&#xff1f;? 跨瀏覽器兼容測試時&#xff0…