應(yīng)用的啟動速度緩慢這是很多開發(fā)者都遇到的一個問題耀态,比如啟動緩慢導(dǎo)致的黑屏轮傍,白屏問題,大部分的答案都是做一個透明的主題茫陆,或者是做一個Splash界面金麸,但是這并沒有從根本上解決這個問題擎析。那么如何從根本上解決這個問題或者做到一定程度的緩解簿盅?
一挥下、應(yīng)用的啟動方式
1、冷啟動:當(dāng)啟動應(yīng)用時桨醋,后臺沒有該應(yīng)用的進(jìn)程棚瘟,這時系統(tǒng)會首先會創(chuàng)建一個新的進(jìn)程分配給該應(yīng)用,這種啟動方式就是冷啟動喜最。
2偎蘸、熱啟動:當(dāng)啟動應(yīng)用時,后臺已有該應(yīng)用的進(jìn)程瞬内,比如按下home鍵迷雪,這種在已有進(jìn)程的情況下,這種啟動會從已有的進(jìn)程中來啟動應(yīng)用虫蝶,這種啟動方式叫熱啟動章咧。
3、溫啟動 :當(dāng)啟動應(yīng)用時能真,后臺已有該應(yīng)用的進(jìn)程赁严,但是啟動的入口Activity被干掉了,比如按了back鍵粉铐,應(yīng)用雖然退出了疼约,但是該應(yīng)用的進(jìn)程是依然會保留在后臺,這種啟動方式叫溫啟動蝙泼。
二程剥、應(yīng)用的啟動時間統(tǒng)計
adb shell am start -W [PackageName]/[PackageName.MainActivity]
執(zhí)行成功后將返回三個測量到的時間:
這里面涉及到三個時間,ThisTime踱承、TotalTime 和 WaitTime倡缠。WaitTime 是 startActivityAndWait 這個方法的調(diào)用耗時,ThisTime 是指調(diào)用過程中最后一個 Activity 啟動時間到這個 Activity 的 startActivityAndWait 調(diào)用結(jié)束茎活。TotalTime 是指調(diào)用過程中第一個 Activity 的啟動時間到最后一個 Activity 的 startActivityAndWait 結(jié)束昙沦。如果過程中只有一個 Activity ,則 TotalTime 等于 ThisTime载荔。
總結(jié):如果只關(guān)心某個應(yīng)用自身啟動耗時盾饮,參考TotalTime;如果關(guān)心系統(tǒng)啟動應(yīng)用耗時懒熙,參考WaitTime丘损;如果關(guān)心應(yīng)用有界面Activity啟動耗時,參考ThisTime工扎。
三徘钥、性能檢查項
從我們Application開始到首頁顯示出來,這個過程肢娘,我們應(yīng)該注意一些什么呈础,將這個過程細(xì)分一下舆驶,會有下面的時間點需要注意。
Application的構(gòu)造器方法——>attachBaseContext()——>onCreate()——>Activity的構(gòu)造方法——>onCreate()——>配置主題中背景等屬性——>onStart()——>onResume()——>測量而钞、布局沙廉、繪制顯示在界面上。
因為上面這些階段全部都是在主線程中執(zhí)行的臼节,任何不經(jīng)意的操作都可能拖慢應(yīng)用的啟動速度撬陵。所以我們不應(yīng)在Application以及Activity的生命周期回調(diào)中做任何費時操作,具體指標(biāo)大概是你在onCreate网缝,onResume巨税,onStart等回調(diào)中所花費的總時間最好不要超過400ms,否則用戶在桌面點擊你的應(yīng)用圖標(biāo)后粉臊,將感覺到明顯的卡頓垢夹。但是有些不得以的任務(wù)又必須在UI顯示之前執(zhí)行。所以我們要將任務(wù)劃分優(yōu)先級维费。
- ** 優(yōu)先級為1的在應(yīng)用啟動時果元,就開始加載**
- 優(yōu)先級為2的在首頁渲染完成后,開始加載
- 優(yōu)先級為3的在首頁渲染完成后犀盟,延遲加載
對于首頁渲染完成后而晒,開始加載,或者延遲加載阅畴,延遲加載的目的就是界面先顯示出來倡怎,然后加載,但是你覺得要延遲多久呢贱枣?在 Android 的高端機型上,應(yīng)用的啟動是非臣嗍穑快的 , 這時候只需要 Delay 很短的時間就可以了, 但是在低端機型上,應(yīng)用的啟動就沒有那么快了,而且現(xiàn)在應(yīng)用為了兼容舊的機型,往往需要 Delay 較長的時間,這樣帶來體驗上的差異是很明顯的。延遲加載有一種方式纽哥。
第一種寫法:直接PostDelay 300ms.
myHandler.postDelayed(mLoadingRunnable, DEALY_TIME);
第二種寫法:優(yōu)化的DelayLoad
getWindow().getDecorView().post(new Runnable() {
@Override
public void run() {
myHandler.post(mLoadingRunnable);
}
});
極力推薦用第二種钠乏,在窗口完成以后進(jìn)行加載,這里面的run方法是在onResume之后運行的春塌。關(guān)于這種懶加載機制晓避,參考Android應(yīng)用啟動優(yōu)化:一種DelayLoad的實現(xiàn)和原理(上篇),給出了詳細(xì)的解釋只壳。
四俏拱、利用TraceView逐個修復(fù)
通過上面我們知道一種懶加載機制,所以我們可以將Application中和首頁的onCreate中的有些耗時任務(wù)吼句,放到首頁渲染完畢后加載锅必。如何找出這些耗時任務(wù),TraceView就派上用場了惕艳,TraceView的用法搞隐,移步我的前面的博客Android性能優(yōu)化第(六)篇---TraceView 分析圖怎么看分蓖?
比如在首頁的onCreate中我們進(jìn)行了用戶啟動上報,這個進(jìn)行懶加載是不是分分鐘減少139毫秒呢尔许?
在比如在Application里面用到了GSON,將String轉(zhuǎn)化成json,我將這個移動到懶加載里面终娃,是不是又減少了100毫秒呢味廊?
在比如,有些Application中做了支付SDK的初始化棠耕,用戶又不會一打開App就要支付余佛,放在Application中加載干嘛?
此處我們這里舉得例子是優(yōu)化了139毫秒和100毫秒的窍荧,其實真正耗時的任務(wù)有的有1秒多辉巡,都被我優(yōu)化完了,所以trace圖中看不到了蕊退,就舉個了這兩個例子郊楣,還有SharedPreferences也是耗時大戶,經(jīng)過檢測保存一個boolean變量耗時120+毫秒以上瓤荔。
利用TraceView可以清楚我們每一個方法的耗時時間净蚤,極大的幫助了我們做優(yōu)化工作阳惹。
五砚著、優(yōu)化思路總結(jié)
1旬蟋、UI渲染優(yōu)化奉瘤,去除重復(fù)繪制窃判,減少UI重復(fù)繪制時間嗤详,打開設(shè)置中的GPU過度繪制開關(guān)礁遣,各界面過度繪制不應(yīng)超過2.5x矾削;也就是打開此調(diào)試開關(guān)后郎逃,界面整體呈現(xiàn)淺色哥童,特別復(fù)雜的界面,紅色區(qū)域也不應(yīng)該超過全屏幕的四分之一褒翰;
2如蚜、根據(jù)優(yōu)先級的劃分,KoMobileApplication的一些初始化工作能否將任務(wù)優(yōu)先級劃分成3,在首頁渲染完成后進(jìn)行加載影暴,比如:PaySDKManager错邦。
3、主線程中的所有SharedPreference能否在非UI線程中進(jìn)行型宙,SharedPreferences的apply函數(shù)需要注意撬呢,因為Commit函數(shù)會阻塞IO,這個函數(shù)雖然執(zhí)行很快妆兑,但是系統(tǒng)會有另外一個線程來負(fù)責(zé)寫操作魂拦,當(dāng)apply頻率高的時候毛仪,該線程就會比較占用CPU資源。類似的還有統(tǒng)計埋點等芯勘,在主線程埋點但異步線程提交箱靴,頻率高的情況也會出現(xiàn)這樣的問題。
4荷愕、檢查BaseActivity,不恰當(dāng)?shù)牟僮鲿绊懰凶覣ctivity的啟動衡怀。
5、對于首次啟動的黑屏問題安疗,對于“黑屏”是否可以設(shè)計一個.9圖片替換掉抛杨,間接減少用戶等待時間。
6荐类、對于網(wǎng)絡(luò)錯誤界面怖现,友好提示界面,使用ViewStub的方式玉罐,減少UI一次性繪制的壓力屈嗤。
7、任務(wù)優(yōu)先級為2吊输,3的恢共,通過下面這種方式進(jìn)行懶加載的方式
getWindow().getDecorView().post(new Runnable() {
@Override
public void run() {
myHandler.post(mLoadingRunnable);
}
});
8、Multidex的使用璧亚,也是拖慢啟動速度的元兇讨韭,必須要做優(yōu)化。后面有空專門寫一篇Multidex癣蟋。
相關(guān)鏈接:
Android性能優(yōu)化之加快應(yīng)用啟動速度http://www.open-open.com/lib/view/open1452821612355.html
手機淘寶性能優(yōu)化全記錄http://www.open-open.com/lib/view/open1452488209370.html
Android客戶端性能優(yōu)化(魅族資深工程師毫無保留奉獻(xiàn))http://blog.tingyun.com/web/article/detail/155#rd
Please accept mybest wishes for your happiness and success !