app的啓動速度在用戶體驗方面是一個重要的指標,當一個可替代行強的app啓動異常緩慢時,必然會致使用戶的流失。java
冷啓動(Cold start)shell
冷啓動是指APP在手機啓動後第一次運行,或者APP進程被kill掉後在再次啓動。bash
可見冷啓動的必要條件是該APP進程不存在,這就意味着系統須要建立進程,APP須要初始化。在這三種啓動方式中,冷啓動耗時最長,對於冷啓動的優化也是最具挑戰的。所以本文重點談論的是對冷啓動相關的優化。微信
溫啓動(Warm start)網絡
App進程存在,當時Activity可能由於內存不足被回收。這時候啓動App不須要從新建立進程,可是Activity的onCrate仍是須要從新執行的。場景相似打開淘寶逛了一圈而後切到微信去聊天去了,過了半小時再次回到淘寶。這時候淘寶的進程存在,可是Activity可能被回收,這時候只須要從新加載Activity便可。多線程
熱啓動(Hot start)app
App進程存在,而且Activity對象仍然存在內存中沒有被回收。能夠重複避免對象初始化,佈局解析繪製。ide
場景就相似你打開微信聊了一會天這時候出去看了下日曆 在打開微信 微信這時候啓動就屬於熱啓動。工具
在最近任務給App加鎖和啓動方式有什麼關係 某些廠商爲了用戶體驗提供了給APP上鎖的功能,目的就是讓用戶本身作主是上鎖的APP不被殺,啓動的時候不會處於冷啓動方式,可是加鎖也不是萬能的,Low memory killer在內存極度吃緊的狀況下也會殺死加鎖APP,在此啓動時也將以冷啓動方式運行。佈局
時間獲取 咱們可使用adb命令啓動應用,來獲取當前應用的啓動時間
adb shell am start -W [packageName]/[.MainActivity]
複製代碼
ThisTime:通常和TotalTime時間同樣,除非在應用啓動時開了一個透明的Activity預先處理一些事再顯示出主Activity,這樣將比TotalTime小。
TotalTime:應用的啓動時間,包括建立進程+Application初始化+Activity初始化到界面顯示。
WaitTime:通常比TotalTime大點,包括系統影響的耗時。
系統建立應用程序進程,應用程序進程就會執行如下操做:
1.建立應用程序對象
2.啓動主線程
3.建立主要Activity
4.繪製視圖(View)
5.佈局屏幕
6.執行初始化繪製
因此優化啓動速度本質上是優化上訴過程,減小這些過程的耗時。
視覺優化
打開一個應用總會有短暫的黑(白)屏的狀況,致使體驗上有卡頓的問題,可設置第一個activity爲透明或者爲其設置一個背景達到視覺上的優化, 以下
application onCreate 優化
1.第三方SDK初始化的處理
Application是程序的主入口,不少三方SDK示例程序中都要求本身在Application OnCreate時作初始化操做。這就是增長Application OnCreate時間的主要元兇,因此須要儘可能避免在Application onCreate時同步作初始化操做。比較好的解決方案就是對三方SDK就行懶加載,不在Application OnCreate()時初始化,在真正用到的時候再去加載。
下面實例對比下ImageLoader在採用懶加載後啓動速度優化。
通常咱們在使用imageLoader時都會在Application onCreate()時在主線程加載:
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
ImageLoaderConfiguration.Builder config =
new ImageLoaderConfiguration.Builder(this);
ImageLoader.getInstance().init(config.build());
}
}
複製代碼
懶加載ImageLoader的工具類示例:
public class ImageUtil {
private static boolean sInit;
private synchronized static void ensureInit() {
if (sInit) {
return;
}
ImageLoaderConfiguration.Builder config =
new ImageLoaderConfiguration.Builder(SecurityCoreApplication.getInstance());
....
// Initialize ImageLoader with configuration.
ImageLoader.getInstance().init(config.build());
sInit = true;
}
public static void display(String uri, ImageView imageView, boolean cacheOnDisk) {
imageView.setImageResource(R.drawable.icon_app_default);
ensureInit();
ImageLoader loader = ImageLoader.getInstance();
if (cacheOnDisk) {
loader.displayImage(uri, imageView);
} else {
loader.displayImage(uri, imageView, OPTIONS_NO_CACHE_DISK);
}
}
}
複製代碼
須要避免Application OnCreate
在主線程作大量耗時操做,例如和IO相關的邏輯,這樣都會影響到應用啓動速度。若是必需要作須要放到子線程中。
多線程避免執行沒必要要的操做
若是應用設置了獨立進程,則在Application onCreate 中須要判斷當前進程,有針對的初始化當前進程須要的功能。
Activity onCreate優化
減小LaunchActivity的View層級,減小View測量繪製時間;使用ViewStub,將無必要的View(如開機廣告)延遲加載
主線程避免I/O操做、反序列化、網絡操做等。