和您一起終身學(xué)習(xí),這里是程序員Android
本篇文章主要介紹 Android 開發(fā)中的部分知識點辐脖,通過閱讀本篇文章狭莱,您將收獲以下內(nèi)容:
一僵娃、App 啟動模式分類
二、App 啟動時間測量與分析
三腋妙、應(yīng)用中冷啟動避免白屏默怨、黑屏方案
四、Framework 層解決冷啟動白屏骤素、黑屏方案
五匙睹、App 啟動優(yōu)化原理
六、App 啟動優(yōu)化簡介
七济竹、App 啟動優(yōu)化方案
八痕檬、在 PMS中 App 啟動優(yōu)化方案
本文將討論如何優(yōu)化應(yīng)用的啟動時間,首先我們需要了解APP
啟動的相關(guān)內(nèi)容规辱。用戶希望APP
能夠快速響應(yīng)并加載谆棺。 一個啟動速度慢的APP
不符合用戶期望,可能會令用戶失望罕袋,并且可能會導(dǎo)致用戶對您的應(yīng)用程序評價不佳改淑,甚至?xí)遁d你的應(yīng)用。
一浴讯、App 啟動模式分類
App 啟動模式分以下 三 類 :
- 冷啟動
- 熱啟動
- 溫?zé)釂?/li>
1.冷啟動
APP
從零開始朵夏,APP
啟動之前,系統(tǒng)沒有為此 APP
創(chuàng)建獨立進(jìn)程榆纽。比如:設(shè)備啟動后仰猖,APP
第一次Launch
或者APP
被Kill
掉后的重啟。這種類型的啟動優(yōu)化存在很大挑戰(zhàn)奈籽,因為Android
系統(tǒng)或應(yīng)用還有其他更多的后臺進(jìn)程在運行饥侵。
啟動流程大致如下:
點擊Launcher 上的 icon開加載app
-->立即顯示白屏或黑屏等
--> Application onCreate
--> Activity Init
----> Activity onCreate
---> 初始化數(shù)據(jù),填充顯示View
---> Activity onResume
等衣屏,詳細(xì)請看下圖:
2. 熱啟動
APP
的熱啟動要比 冷啟動簡單得多躏升,內(nèi)存開銷也更低。APP
熱啟動時候狼忱,所有的系統(tǒng)都是把你的Activity
帶到前臺膨疏。如果APP
的所有Activity
仍駐留在內(nèi)存中,則APP
可以避免重復(fù)對象初始化钻弄、布局繪制和顯示等工作佃却。
如果APP
在內(nèi)存中被清理掉,比如調(diào)用ontrimmemory()
窘俺,當(dāng)響應(yīng)熱啟動時饲帅,這些對象將重新被創(chuàng)建。
熱啟動與冷啟動相同的屏幕行為:
系統(tǒng)進(jìn)程會顯示一個空白屏幕,直到應(yīng)用程序完成渲染后將此空白屏幕移除掉洒闸,此屏幕創(chuàng)建會在加載APP
時候立即創(chuàng)建染坯,如需查看創(chuàng)建流程,需要查看PhoneWindosManger
中AddWindows
方法丘逸。
3. 溫?zé)釂?/h3>
處于冷啟動與熱啟動之間单鹿,既包含一些冷啟動的操作,又含有部分熱啟動的功能深纲。例如以下兩種狀態(tài):
1. 用戶退出APP
后重新Launch
仲锄。
此時此APP
的進(jìn)程可能會存在,然鵝湃鹊,Activity
必須重新創(chuàng)建并調(diào)用onCreate
方法
2. APP 被緩存中清理掉時儒喊。
此時用戶重新Launch APP
時,此APP
的進(jìn)程和Activity
都需要重新創(chuàng)建币呵,但是任務(wù)棧中會保存部分APP
實例數(shù)據(jù)(bundle類型
)傳遞個Activity onCreate
方法
二怀愧、App 啟動時間測量與分析
為了更加準(zhǔn)確的測量 APP
啟動的耗時,請務(wù)必使用User
版本進(jìn)行驗證余赢。UserDebug
或者eng
版本會開很多調(diào)試開關(guān)影響測試的正常結(jié)果芯义。
如何獲取APP
啟動時間,請看以下測量方法
ps: 以下測試方法請在Android 4.4(含) 以上的版本進(jìn)行
1.通過 adb 命令測量APP 冷啟動時間
使用adb
命令直接啟動APP
進(jìn)而測量APP
啟動耗時 的方法如下:
adb shell am start -W [packageName]/[packageName.MainActivity]`
或
adb [-d|-e|-s <serialNumber>] shell am start -S -W [packageName]/[packageName.MainActivity] -c android.intent.category.LAUNCHER -a android.intent.action.MAIN
如要測量的app沒有源碼妻柒,比如:QQ
扛拨,請用以下命令獲取, 當(dāng)前獲取焦點的Activity
举塔,方法信息如下:
adb shell dumpsys activity |findstr "mFocused"
APP
啟動時間詳情 請看以下圖片中橢圓 紅框區(qū)域內(nèi)容绑警。
2.通過 adb logcat 查看APP 啟動時間
在Log
中,主要是 通過分析 logcat
中APP
在 ActivityManager: Displayed
的時間值 央渣,此時間值包含以下時間綜合信息:
- Launch 進(jìn)程
- 初始化對象
- 創(chuàng)建并初始化Activity
- 填充布局
- 第一次繪制app 內(nèi)容
比如下圖:ProgramAndroid
程序啟動時間700ms
3. 在代碼中測量app啟動性能的方法如下:
在Activity
代碼用調(diào)用 reportFullyDrawn();
方法计盒,將繪制完成后信息反饋到Log
上,此方法跟logcat
中查看的時間相似芽丹。
比如自己運行ProgramAndrod
APP
的啟動時間信息如下
11-24 11:47:00.363 982 1191 I ActivityManager:
Fully drawn com.programandroid/.MainActivity: +998ms
4. 使用Systrace 工具分析app啟動時間
當(dāng)然如果感覺上述方法比較麻煩章郁,可以使用Systrace
工具進(jìn)行分析,工具分析情況志衍,下次貼出。
三楼肪、應(yīng)用中冷啟動避免白屏、黑屏方案
手機(jī)中 APP
首次啟動(未在最近任務(wù)列表中惹悄,或已經(jīng)運行過春叫,但在最近任務(wù)列表中已清除啟動記錄)稱為冷啟動,此時打開APP
時候回閃白屏或黑屏,特別是當(dāng)系統(tǒng)主題為黑色或白色時候比較明顯暂殖。
在應(yīng)用端規(guī)避掉打開APP
閃白屏价匠、黑屏問題,主要是從android:windowIsTranslucent
上讓白屏變透明呛每,進(jìn)而不讓用戶看到白屏踩窖、黑屏現(xiàn)象。
但是晨横,此解決方案會導(dǎo)致在Launcher
中點擊APP`` icon
是會有輕微的卡頓現(xiàn)象洋腮,此現(xiàn)象會讓用戶誤認(rèn)為手機(jī)卡,APP
啟動慢手形,從而將打開APP
閃白屏的黑鍋甩給手機(jī)制造廠商啥供。
1. 透明樣式Theme 解決方案如下:
1. 自定義透明樣式
在res/values/style.xml
中自定義樣式
2. App 啟動入口Activity 中使用自定義樣式
注意: windowDisablePreview =false
屬性可以不讓白屏顯示,失去中間白屏過度库糠,會給用戶帶來不是太好的體驗伙狐,比如點擊后需要稍微等一下才會打開APP
,會讓用戶錯誤的懷疑自己是否成功點擊過icon瞬欧。Google 很不推薦此種做法贷屎。
2. 使用app logo等圖片樣式使用方法如下
1. 自定義Theme
2. 為 要啟動的Activity設(shè)置自定義樣式
3. 同樣也可以在Java類中的 設(shè)置樣式
此方法也是Google
推薦的方法,建議大家可以用自定義Theme
替換掉系統(tǒng)中的白屏黍判,當(dāng)然也可以搞成什么廣告頁面等等豫尽。
四、 Framework 層解決冷啟動白屏顷帖、黑屏方案
打開APP
閃黑屏美旧、白屏的根本原因在于PhonewindowManger
中的addStartingWindow
方法。
Framwork
上 這樣修改后贬墩,會將白色屏幕替換成我們客制化的顏色榴嗅,此修改會影響到所有APP
的啟動。
五陶舞、App 啟動優(yōu)化原理
L
版本之后嗽测,手機(jī)上所有APP
都要經(jīng)過dex2oat
處理之后,才能運行.
dex2oat
是將原來的dex文件預(yù)先的翻譯處理肿孵,從而加快APP
運行的時間唠粥,但由于某些APP
比較復(fù)雜,優(yōu)化的時間可能會比較長停做,進(jìn)而給用戶感覺運行卡頓晤愧。
dex2oat
優(yōu)化是以dex
文件中的method
為單位,dex2oat
會根據(jù)需要優(yōu)化一定量的method蛉腌,也就是說并不是優(yōu)化的method
都會被翻譯成oat
模式官份。
根據(jù)優(yōu)化的method
的量的多少只厘,可以分為如下的幾種模式:
六、 App 啟動優(yōu)化簡介
Android L
之后的版本舅巷,如無特殊處理羔味,APP
啟動模式為Speed
模式,此模式性能較好钠右,但優(yōu)化之后的文件占用空間比較大赋元。不同模式可以看上面MTK 提供的參考標(biāo)準(zhǔn)。
對APP
的優(yōu)化是通過dex2oat
去執(zhí)行的爬舰,優(yōu)化模式的參數(shù)是有外界調(diào)用dex2oat
方法傳遞的參數(shù)控制们陆,如無傳遞參數(shù),默認(rèn)參數(shù)Speed
情屹。
那么調(diào)用dex2oat
的路徑有哪些呢坪仇?
1.安裝APP時優(yōu)化
通過 Framework 下的PackageManagerService
將參數(shù)傳遞給 mAppInstallDir
,然后mAppInstallDir
調(diào)用dex2oat
垃你,因此此種方式的優(yōu)化模式通過PMS控制椅文。
此種模式是將APP
的路徑,優(yōu)化之后的oat
存放路徑惜颇,傳遞給dex2oat
皆刺。
但是由于內(nèi)容可能發(fā)生改變,我們有可能無法在dex2oat
對APP
加以識別凌摄,所以羡蛾,這時候,可以在installd
或者PMS
中加以判斷锨亏,是否是我們認(rèn)為安裝比較慢的APP
痴怨,如果是的話,則改變其優(yōu)化模式器予。
2. APP自身優(yōu)化插件時
此種模式往往會指定模式為speed
模式或者不指定浪藻,在優(yōu)化之后的保存路徑中,攜帶APP
的包名乾翔。
目前有些 apk
像Facebook
爱葵、微信WeChat
等 APP
,應(yīng)用本身較大且代碼復(fù)雜度高反浓,可能會出現(xiàn)安裝失敗萌丈,安裝慢等問題。
安裝失敗是由于dex2oat
進(jìn)程編譯時間過久打到了timeout
雷则。
安裝慢當(dāng)然就是dex2oat
做的compiler
久的原因辆雾。
另外,像 微信 WeChat
這種apk
在啟動應(yīng)用的時候是會優(yōu)化插件的(而不是在安裝的時候優(yōu)化)
巧婶,這樣就會導(dǎo)致應(yīng)用lunch
時間過久乾颁,給用戶的感覺就是很晚才入,手機(jī)卡頓等鍋艺栈,讓手機(jī)廠商背負(fù)英岭。在需更改優(yōu)化的模式,加快安裝的時間時湿右,請注意此修改會降低 APP
運行的性能诅妹。
注意:APP
安裝 / lunch時間的長短取決于CPU核心數(shù),8 核CPU 肯定比 4 核 CPU優(yōu)化要快毅人,除此之外吭狡,還取決于EMMC的性能 ,memory等系統(tǒng)因素丈莺。
七划煮、App 啟動優(yōu)化方案
對于APP
優(yōu)化目前有3個地方可以進(jìn)行處理。
1. PackageManagerService中
這個地方是安裝APP
必經(jīng)之路缔俄,代碼存放地址如下:
2. installd的commands.cpp中
這也是安裝APP
的必經(jīng)之路 弛秋,代碼存放地址如下:
3. dex2oat 中
ex2oat
是所有APP
或者jar
包的必經(jīng)之路,但是由于傳遞給dex2oat
的參數(shù)有限俐载,所以可能無法識別蟹略。
因此,對于安裝APP
可以在PMS
中修改遏佣,而對于jar
包可以在dex2oat
當(dāng)中修改挖炬。
因為PMS
中我們可以知道APP
的pkg
信息,這個是每一個APP
唯一的状婶。
而對jar
包來說意敛,由于每一個APP
在優(yōu)化的時候,喜歡把優(yōu)化之后的jar
包放在自己安裝的APP
路徑下面太抓。所以空闲,可以利用這個特性進(jìn)行判斷 。
八走敌、 在 PMS中 App 啟動優(yōu)化方案
ps: 此解決方案適用于Android N
版本
主要修改PackageDexOptimizer.java
文件的 performDexOptLI
方法中進(jìn)行優(yōu)化碴倾。
在這函數(shù)中,可以判斷傳遞下來的pkg
是否是我們需要的APP
掉丽,如果是的話跌榔,將targetCompilerFilter
設(shè)置為speed-profile
。
speed-profile
會在安裝的時候采用 interperter-only
捶障,然后僧须,運行一段時間之后,會將那些常用的方法優(yōu)化成為speed
模式项炼。也就是說是有選擇性的優(yōu)化担平。
至此示绊,本篇已結(jié)束。轉(zhuǎn)載網(wǎng)絡(luò)的文章暂论,小編覺得很優(yōu)秀面褐,歡迎點擊閱讀原文,支持原創(chuàng)作者取胎,如有侵權(quán)展哭,懇請聯(lián)系小編刪除,歡迎您的建議與指正闻蛀。同時期待您的關(guān)注匪傍,感謝您的閱讀,謝謝觉痛!