關(guān)于Android冷啟動(dòng)耗時(shí)優(yōu)化詳解
1,背景
最近開發(fā)了一個(gè)新的App,前期工期緊,做的比較粗放,上線以后發(fā)現(xiàn)App啟動(dòng)時(shí)間比較長(zhǎng),達(dá)到3秒,
啟動(dòng)有白屏,體驗(yàn)也不好,這個(gè)只能后期優(yōu)化了,最好是前期開發(fā)就考慮的
2,調(diào)研
2.1,Android中啟動(dòng)的方式
1,冷啟動(dòng):如果App啟動(dòng)時(shí),后臺(tái)沒有該應(yīng)用進(jìn)程,那么系統(tǒng)會(huì)重新創(chuàng)建一個(gè)進(jìn)程分配給該應(yīng)用,這種啟動(dòng)方式就是冷啟動(dòng)
2,熱啟動(dòng):如果App啟動(dòng)時(shí),后臺(tái)有該應(yīng)用進(jìn)程,那么系統(tǒng)就是直接使用已有進(jìn)程
從兩種啟動(dòng)方式的含義就可以看出,冷啟動(dòng)比較耗時(shí),熱啟動(dòng)一般比較快,我們要做的啟動(dòng)優(yōu)化一般做的就是冷啟動(dòng)優(yōu)化
2.2,冷啟動(dòng)流程
系統(tǒng)創(chuàng)建應(yīng)用進(jìn)程時(shí)間我們一般無法優(yōu)化,這個(gè)是系統(tǒng)創(chuàng)建簡(jiǎn)單的流程
我們可以優(yōu)化的地方就是
1,Application
2,SplashActivity
3,MainActivity
2.3,啟動(dòng)時(shí)間
1,通過命令
adb shell am start -W [packageName]/[packageName.MainActivity]
這個(gè)時(shí)候,如果啟動(dòng)的activity在Manifest中沒有設(shè)置export:true,可能無法通過命令打開,需要設(shè)置這個(gè)
2,自己埋點(diǎn)
從上面的啟動(dòng)過程就可以知道,Android冷啟動(dòng),系統(tǒng)要先創(chuàng)建一個(gè)進(jìn)程,然后創(chuàng)建Application,系統(tǒng)創(chuàng)建進(jìn)程的過程,我們可以在Application的attachBaseContext方法中開始埋點(diǎn)
/** * 統(tǒng)計(jì)冷啟動(dòng)各個(gè)時(shí)間點(diǎn)的耗時(shí) */ public class StartLogHelper { private static final String TAG = "StartLogHelper"; private static long startTime; /** * 設(shè)置開始時(shí)間,暫時(shí)放到啟動(dòng)的時(shí)間,放到Application的attachBaseContext方法中 * @param start */ public static void setStart(long start){ startTime = start; } /** * application初始化的時(shí)間,放到Application的onCreate方法最后 */ public static void getApplicationTime(){ long end = System.currentTimeMillis(); DebugLog.e(TAG,"==================getApplicationTime==" + (end - startTime)); } /** * 歡迎頁(yè)初始化的時(shí)間 */ public static void getWelcomeTime(){ long end = System.currentTimeMillis(); DebugLog.e(TAG,"==================getWelcomeTime==" + (end - startTime)); } /** * Main頁(yè)面初始化的時(shí)間 */ public static void getMainTime(){ long end = System.currentTimeMillis(); DebugLog.e(TAG,"==================getMainTime==" + (end - startTime)); }
3,在studio的logcat日志中
在logcat日志中輸入應(yīng)用的包名
然后就可以看到各個(gè)階段的時(shí)間了
3,方案
從調(diào)研冷啟動(dòng)的原理就可以得出,我們要優(yōu)化的地方
1,冷啟動(dòng)白屏現(xiàn)象
冷啟動(dòng)的時(shí)候,我們發(fā)現(xiàn)會(huì)有白屏現(xiàn)象,會(huì)先出現(xiàn)一個(gè)白屏,然后在出現(xiàn)歡迎頁(yè)的UI,這個(gè)跟系統(tǒng)的設(shè)置的背景windowBackground有關(guān)系
解決方案:
在歡迎頁(yè)設(shè)置一個(gè)自定義的theme屬性
SplashActivity的清單文件設(shè)置 android:theme="@style/SplashScreenTheme” SplashScreenTheme屬性定義 <style name="SplashScreenTheme" parent="Theme.AppCompat.NoActionBar"> <item name="android:windowBackground">@drawable/bg_splash</item> </style> bg_splash定義 <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@android:color/white" /> <bitmap android:antialias="true" android:gravity="center" android:src="@drawable/bg_show" /> </item> </layer-list>
其中bg_show的圖片和歡迎頁(yè)的初始圖片一樣,這樣就可以實(shí)現(xiàn)啟動(dòng)白屏的樣式 和歡迎頁(yè)樣式一樣,給人沒有白屏的感覺
2,啟動(dòng)時(shí)間優(yōu)化
我們從上面的啟動(dòng)時(shí)間就可以知道
1,Application onCreate中初始化三方sdk耗時(shí)
public class AppConfigHelper { public void setAppConfig(Application application){ addSyncTask(application); addAsyncTask(application); TaskConfigManager.getInstance().startInit(); } private void addSyncTask(Application application) { TaskConfigManager.getInstance().addTask(new ZMLTask("oneLogin") { @Override public void run() { JVerifyHelper.init(application); } }); } }
把需要在Application中同步執(zhí)行的放到一起
可以異步執(zhí)行的放到一起
2,首頁(yè)耗時(shí)方法
到首頁(yè)的時(shí)候,我們埋點(diǎn)的時(shí)間,小于用戶看到數(shù)據(jù)的時(shí)間 這個(gè)是因?yàn)槭醉?yè)加載的數(shù)據(jù)比較多 我們首頁(yè)同時(shí)加載了7個(gè)Fragment,同時(shí)請(qǐng)求10個(gè)以上接口
1,首頁(yè)做懶加載,保證App啟動(dòng)接口只請(qǐng)求3個(gè)左右
2,首頁(yè)UI優(yōu)化,同時(shí)顯示出ui以后在執(zhí)行后面邏輯處理
3,首頁(yè)部分不重要邏輯做延時(shí)加載,比如請(qǐng)求升級(jí)彈窗等
總結(jié)
到此這篇關(guān)于關(guān)于Android冷啟動(dòng)耗時(shí)優(yōu)化詳解的文章就介紹到這了,更多相關(guān)Android冷啟動(dòng)優(yōu)化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android仿蘋果關(guān)機(jī)界面實(shí)現(xiàn)代碼
這篇文章主要為大家詳細(xì)介紹了Android仿蘋果關(guān)機(jī)界面的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09android實(shí)現(xiàn)動(dòng)態(tài)顯示隱藏進(jìn)度條
這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)動(dòng)態(tài)顯示隱藏進(jìn)度條,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08Android中控件GridView實(shí)現(xiàn)設(shè)置行列分割線的方法示例
這篇文章主要介紹了利用Android中控件GridView實(shí)現(xiàn)設(shè)置行列分割線的方法,文中給出了詳細(xì)的介紹與示例代碼,相信對(duì)大家具有一定的參考價(jià)值,有需要的朋友們下面來一起看看吧。2017-01-01Android應(yīng)用中使用Fragment組件的一些問題及解決方案總結(jié)
這里我們講的Fragment主要探討的是support庫(kù)中的Fragment,包括Fragment常遇到的crash崩潰問題,嵌套Fragment收不到onActivityResult()回調(diào)以及一些常用tips等,需要的朋友可以參考下2016-05-05