極力推薦文章:歡迎收藏
Android 干貨分享
本篇文章主要介紹 Android
開發中 開關機 重啟時間 部分知識點,通過閱讀本篇文章,您將收獲以下內容:
一、 zygote,預加載class、resources
二、 開機動畫進程 bootanimation
三、SystemServer.java 代碼邏輯
四、 非必要服務請放在system_server進程外啟動
五、kernel init 時間過長
六、排查驅動設備初始化是否完成
七、apk dex2oat時間過長
八、 盡量少把APP設置為persist
九、 定頻定核,調高CPU頻率,會帶來一定的功耗
十、PackageManagerService 掃描apk 優化
十一、關機時間優化
十二、 優化第三apk 后台服務
十三、 谷歌官方參考資料
開機性能是使用功能和其它因素多方面平衡的結果,片面追求單方面的性能沒有太大意義;
有些產品設計開機動畫非常酷炫,動畫圖片過多、高幀率會影響開機速度,這時就需要看是開機速度優先還是體驗優先;
具體開機優化方案如下:
一、zygote,預加載class、resources
zygote
預加載多了,會影響開機時間,所以需要優化預加載內容。
MTK
平台 開機時間信息保存在 /proc/bootprof
下,或mtklog/mobilelog/Aplog
下。
bootprof
舉例如下:
<< /proc/bootprof >>:
----------------------------------------
0 BOOT PROF (unit:msec)
----------------------------------------
1612 : preloader
1915 : lk (Start->Show logo: 981)
----------------------------------------
34.132076 : ON
88.563768 : 1-swapper/0 : initcall: of_init 17.915384ms
131.311461 : 1-swapper/0 : initcall: customize_machine 24.395769ms
164.462461 : 1-swapper/0 : initcall: param_sysfs_init 16.619385ms
228.096692 : 1-swapper/0 : initcall: event_trace_init 30.488846ms
297.817461 : 1-swapper/0 : initcall: populate_rootfs 53.605462ms
353.950769 : 1-swapper/0 : initcall: mt_i2c_init 16.164154ms
2367.197389 : 1-swapper/0 : probe: probe=i2c_device_probe drv=mt6311(c0e57f6c) 1998.596236ms
2367.745697 : 1-swapper/0 : initcall: mt6311_init 1999.229312ms
2385.294389 : 1-swapper/0 : probe: probe=platform_drv_probe drv=musb-hdrc(c0e5876c) 16.914000ms
2385.426543 : 1-swapper/0 : initcall: musb_init 17.640462ms
2503.717235 : 1-swapper/0 : probe: probe=platform_drv_probe drv=mtk-msdc(c0ea070c) 36.834692ms
2540.662159 : 1-swapper/0 : probe: probe=platform_drv_probe drv=mtk-msdc(c0ea070c) 36.847000ms
2542.779389 : 1-swapper/0 : initcall: mt_msdc_init 76.216231ms
2852.160621 : 6-kworker/u8:0 : probe: probe=i2c_device_probe drv=fts_ts(c0e9b9cc) 234.830693ms
2855.127621 : 6-kworker/u8:0 : probe: probe=platform_drv_probe drv=mtk-tpd(c0e78d4c) 238.288846ms
2869.938159 : 1-swapper/0 : initcall: battery_init 253.557308ms
2879.950852 : 1-swapper/0 : Kernel_init_done
... ...
29772.775531 : 727-system_server : AMS:systemReady
29786.000916 : 727-system_server : AMS:AMS_READY
30075.941840 : 727-system_server : AP_Init:[service]:[com.google.android.inputmethod.latin]:[com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME]:pid:975
30116.813224 : 727-system_server : AP_Init:[service]:[com.android.systemui]:[com.android.systemui/.ImageWallpaper]:pid:986:(PersistAP)
30244.397225 : 919-system-server-i : AP_Init:[]:[WebViewLoader-armeabi-v7a]:pid:1011
... ...
31891.278382 : 727-system_server : Android:SysServerInit_END
32461.362615 : 763-ActivityManager : AMS:ENABLE_SCREEN
32463.281768 : 770-android.display : AP_Launch: com.android.settings/.FallbackHome 665ms
36239.598547 : 763-ActivityManager : AP_Init:[broadcast]:[com.android.dialer]:[com.android.dialer/.app.voicemail.LegacyVoicemailNotificationReceiver]:pid:1524
38411.551244 : 325-Binder:300_1 : BOOT_Animation:END
38411.595629 : OFF
----------------------------------------
================ END of FILE ===============
1.預加載Class
因為少加載類會影響APP
啟動速度,開機過程會涉及到APP
啟動,此地沒有優化空間;
預加載Class
類路徑 /frameworks/base/config/preloaded-classes
2.預加載資源
/frameworks/base/core/res/
下的資源文件會被打包成 framework-res.apk
。
此時需要確保沒有冗余的 資源圖片,可以挨個檢查圖片、XML
是否在系統中有用到。
二、開機動畫進程 bootanimation
開機動畫保存在手機system/media
下,
開機動畫要求:
圖片越少越好,不宜占用過大的內存空間,否則系統會浪費在加載開機動畫圖片上,這樣導致開機時間慢,就不好了。
兩種開機動畫
1.播放開機聲音
開機動畫需要等待開機鈴聲播放完,動畫才能退出,開機才能完成;
所以 開機鈴聲的mp3文件不能過長,最好不要超過system_server
啟動時間;
通過查看bootprof
文件可以大致確定system_server
啟動時間。
system_server 啟動時間舉例如下:
23340.916362 : 727-system_server : Android:SysServerInit_START
24217.928364 : 727-system_server : Android:PackageManagerService_Start
....
31891.278382 : 727-system_server : Android:SysServerInit_END
2.不播放開機聲音
不播放開機聲音,不會影響開機時間,bootanimation.zip
中圖片越少越好。
三、 SystemServer.java 代碼邏輯
不建議更改SystemServer
代碼邏輯,修改風險較大,除非對開機速度有特別嚴苛的要求才修改:
/frameworks/base/services/java/com/android/server/SystemServer.java
可以優化的Service
舉例如下:
DropBoxManagerService
和調試相關,可以異步加載或者直接閹割掉
PinnerService
沒有配置相關則可以去除;
其他Service
需要通過查看耗時挨個排查,耗時log
查看如下:
Line 126: 07-12 18:01:14.616410 1024 1024 I SystemServer: InitBeforeStartServices
Line 127: 07-12 18:01:14.616637 1024 1024 I SystemServer: Entered the Android system server!
Line 128: 07-12 18:01:14.881713 1024 1024 D SystemServerTiming: InitBeforeStartServices took to complete: 265ms
Line 129: 07-12 18:01:14.881877 1024 1024 I SystemServer: StartServices
Line 130: 07-12 18:01:14.881922 1024 1024 I SystemServer: Reading configuration...
Line 131: 07-12 18:01:14.881945 1024 1024 I SystemServer: ReadingSystemConfig
Line 132: 07-12 18:01:14.882617 1024 1024 D SystemServerTiming: ReadingSystemConfig took to complete: 1ms
Line 133: 07-12 18:01:14.882714 1024 1024 I SystemServer: StartInstaller
Line 135: 07-12 18:01:14.883365 1024 1091 D SystemServerInitThreadPool: Started executing ReadingSystemConfig
Line 136: 07-12 18:01:14.887243 1024 1024 D SystemServerTiming: StartInstaller took to complete: 5ms
Line 137: 07-12 18:01:14.887310 1024 1024 I SystemServer: DeviceIdentifiersPolicyService
Line 139: 07-12 18:01:14.889138 1024 1024 D SystemServerTiming: DeviceIdentifiersPolicyService took to complete: 2ms
Line 140: 07-12 18:01:14.889247 1024 1024 I SystemServer: StartActivityManager
Line 144: 07-12 18:01:14.954297 1024 1091 D SystemServerInitThreadPool: Finished executing ReadingSystemConfig
Line 162: 07-12 18:01:15.720682 1024 1024 D SystemServerTiming: StartActivityManager took to complete: 831ms
Line 163: 07-12 18:01:15.720717 1024 1024 I SystemServer: StartPowerManager
Line 165: 07-12 18:01:15.737378 1024 1024 D SystemServerTiming: StartPowerManager took to complete: 17ms
Line 166: 07-12 18:01:15.737495 1024 1024 I SystemServer: InitPowerManagement
Line 167: 07-12 18:01:15.739204 1024 1024 D SystemServerTiming: InitPowerManagement took to complete: 2ms
Line 168: 07-12 18:01:15.739280 1024 1024 I SystemServer: StartRecoverySystemService
Line 170: 07-12 18:01:15.742151 1024 1024 D SystemServerTiming: StartRecoverySystemService took to complete: 3ms
Line 172: 07-12 18:01:15.750585 1024 1024 I SystemServer: StartLightsService
Line 174: 07-12 18:01:15.752248 1024 1024 D SystemServerTiming: StartLightsService took to complete: 2ms
Line 175: 07-12 18:01:15.752348 1024 1024 I SystemServer: StartSidekickService
Line 176: 07-12 18:01:15.752405 1024 1024 D SystemServerTiming: StartSidekickService took to complete: 0ms
Line 177: 07-12 18:01:15.752434 1024 1024 I SystemServer: StartDisplayManager
Line 179: 07-12 18:01:15.778824 1024 1024 D SystemServerTiming: StartDisplayManager took to complete: 26ms
Line 180: 07-12 18:01:15.778955 1024 1024 I SystemServer: WaitForDisplay
Line 184: 07-12 18:01:15.798983 1024 1024 D SystemServerTiming: WaitForDisplay took to complete: 20ms
Line 185: 07-12 18:01:15.799476 1024 1024 I SystemServer: StartPackageManagerService
Line 216: 07-12 18:01:18.624952 1024 1131 D SystemServerInitThreadPool: Started executing prepareAppData
Line 217: 07-12 18:01:18.834938 1024 1131 D SystemServerTimingAsync: AppDataFixup took to complete: 209ms
Line 226: 07-12 18:01:19.226578 1024 1024 D SystemServerTiming: StartPackageManagerService took to complete: 3427ms
Line 227: 07-12 18:01:19.226960 1024 1024 I SystemServer: StartOtaDexOptService
Line 229: 07-12 18:01:19.230308 1024 1024 D SystemServerTiming: StartOtaDexOptService took to complete: 3ms
Line 230: 07-12 18:01:19.230339 1024 1024 I SystemServer: StartUserManagerService
Line 232: 07-12 18:01:19.231780 1024 1024 D SystemServerTiming: StartUserManagerService took to complete: 1ms
Line 233: 07-12 18:01:19.231879 1024 1024 I SystemServer: InitAttributerCache
Line 234: 07-12 18:01:19.232738 1024 1024 D SystemServerTiming: InitAttributerCache took to complete: 1ms
四、 非必要服務請放在system_server進程外啟動
system_server
特定的服務導致開機變慢,比如:指紋系統;
非必要的服務可以放在system_server
進程外啟動;
五、 kernel init 時間過長
kernel init
需要先看一下客戶的版本上init.rc
文件相對Driver only
版本是否有添加新的init
,這些是否都是必須添加的。
在uartlog
中,需要查關鍵字 cut here ,找到在kernel init
過程中,頻繁打出的這些call stack
,看這些call stack
,排查一下貴司所客制化的點。
六、排查驅動設備初始化是否完成
在uartlog
中排查驅動設備初始化是否有完成或延時較長。
比如之前驅動代碼異常問題,耗時8s
,這個有很大優化空間。
七、 apk dex2oat時間過長
如果是刷機后第一次因為對apk進行dex2oat
導致的開機慢:
bootprof
文件中包含 PMS:performDexOpt,說明在編譯時沒有打開dex2oat
選項;
可以按照下面修改
在/device
和/build
目錄下,修改下面的宏,具體下面3
個宏的位置可以在代碼中搜索一下:
build/core/dex_preopt.mk
WITH_DEXPREOPT := true
WITH_DEXPREOPT_PIC := true
DONT_DEXPREOPT_PREBUILTS := false //或者注釋掉
Log
舉例:
67720.299622 : 1211-system_server : PMS:performDexOpt:com.mediatek.ims
67727.107469 : 1211-system_server : PMS:performDexOpt:com.google.android.ext.services
67732.884007 : 1211-system_server : PMS:performDexOpt:com.android.providers.telephony
67740.281545 : 1211-system_server : PMS:performDexOpt:com.micromaxinfo.coreupdater
67750.098776 : 1211-system_server : PMS:performDexOpt:com.touchtype.swiftkey
82794.094658 : 1211-system_server : PMS:performDexOpt:com.mediatek.fwk.plugin
82798.845812 : 1211-system_server :
.......
116880.481509 : 1211-system_server : PMS:performDexOpt:com.android.keychain
116884.277509 : 1211-system_server : PMS:performDexOpt:com.android.chrome
116901.748740 : 1211-system_server : PMS:performDexOpt:com.android.gallery3d
116909.980047 : 1211-system_server :
126659.802071 : 1211-system_server : PMS:performDexOpt:com.google.android.syncadapters.calendar
126665.240840 : 1211-system_server : PMS:performDexOpt:com.android.managedpr
134272.287243 : 1211-system_server : PMS:performDexOpt:com.jio.adc.embedded
134581.037782 : 1211-system_server : PMS:performDexOpt:com.android.wallpaperbackup
134583.934936 : 1211-system_server : PMS:performDexOpt:com.android.providers.blockednumber
134589.891166 : 1211-system_server :
137465.599866 : 1211-system_server : PMS:performDexOpt:com.android.captiveportallogin
八、盡量少把APP設置為persist
1. 優化每一個有源碼的persist APP
;使他們啟動盡可能快;
比如以下persist APP
請盡量優化。
- 1.com.android.systemui(PersistAP)
- 2.com.mediatek.ims(PersistAP)
- 3.com.android.phone(PersistAP)
- 4.com.android.settings
2. 精簡apk
包
(1)刪除沒有用到的,圖片、資源文件、沒有用到的 jar
包文件、不需要使用的so
文件;
(2)預置自己的APP
,假如設備只會加載drawable-xxhdpi
中的資源,那么可以在drawable
包 重復的資源可以直接刪除;
(3)預置自己的APP
,假如設置只支持英文,values-da、values-fa
這樣的多語言支持資源都 可以刪除;
(4)apk
中只保留和系統適配的so
文件,比如:armv7
和arm64
的so
文件;
-
App
的onCreate
方法中不要用耗時的代碼片段。 -
修改
app
的啟動模式
通過修改--compiler-filter
為 speed、quick、speed-profile
來提高apk
的啟動速度;
speed 模式優化的類較多,這時優化后的vdex、odex
的文件較大,應用啟動過程包括映射apk
文件的過程,文件偏大導致有一定的時間損耗;
但speed
模式優化后,Java
類執行更快;所以這個需要針對具體的應用多次驗證,沒有普適性;
九、 定頻定核,調高CPU頻率,會帶來一定的功耗
以6763
的O1
版本代碼為例:
在Init
進程中進行如下修改。
/system/core/rootdir/init.rc
on early-init
#mtk begin
write /proc/ppm/policy/ut_fix_core_num "4 4"
write /proc/ppm/policy/ut_fix_freq_idx "0 0"
#mtk end
on property:sys.boot_completed=1
bootchart stop
#mtk begin
write /proc/ppm/policy/ut_fix_core_num "-1 -1"
write /proc/ppm/policy/ut_fix_freq_idx "-1 -1"
#mtk end
10.PackageManagerService 掃描apk 優化
1.scanDirTracedLI
(1)減少預置APP
的數量(對開機速度會有較為明顯的提升);
(2)刪除沒有必要的apk
包;
(3)單線程scan
分區里面的apk
並不一定能充分使用IO
資源,嘗試改為多線程異步scan
;(部分手機廠商有做出此種修改,且效果較為明顯,但修改需謹慎);
(4)精簡系統,把系統中用不到的apk
包、有重復功能的apk
移除(比如:我司代碼默認包含 有計算器APP
,如果貴司有自己單獨的計算器APP
則可以移除我司apk
),這樣既可以使系統有更大的剩余存儲空間又可以減少scan
的時間,加快開機;
十一、關機時間優化
以MTK6763
為例:
[ro.mediatek.version.branch]: [alps-mp-o1.mp1]
可以把下面這個時間改為1s
(貴司可以自己測試找一個最優值),然后關機音頻控制在1s
(否則音頻播放不完整),或者關機時不播放鈴聲,把這個值設置為10ms
;
/frameworks/base/services/core/java/com/android/server/power/ShutdownThread.java
149 // Shutdown Animation
150 private static final int MIN_SHUTDOWN_ANIMATION_PLAY_TIME = 1 * 1000;
十二、優化第三apk 后台服務
關機時間長的另外一個原因有可能是后台應用亂跑;
尤其國內一些有保活的APP
,在后台都在積極搶占CPU
,在手機系統資源緊張時對系統的性能影響是非常大的;
手機使用過程中,適當的限制后台進程的數量,會一定程度提高系統性能和更快的關機;
還有些APP
一直保持有1
個像素的懸浮窗,使自己一直為可見進程,可見進程能更多的占用系統資源,手機系統可以增加懸浮窗的權限管控開關只有獲取到了才允許懸浮,可以更加合理的非配系統資源。
13.谷歌官方參考資料
至此,本篇已結束,如有不對的地方,歡迎您的建議與指正。同時期待您的關注,感謝您的閱讀,謝謝!