天天看點

這些方法助你優化 Android 啟動速度

一、直奔主題

來自使用者、測試、産品、包括開發人員回報:

app啟動很慢,歡迎頁停留太久或者啟動黑屏等等,但有時候又不會。

起初一直不太重視,後來随着産品疊代更新,發現啟動速度慢的問題越來越明顯,已經影響到使用者體驗,甚至為了加快啟動速度而要發一個更新包。于是決定優化一下啟動速度,研究之後發現,還是有很多可以拿出來分享的;

二、基礎知識

冷啟動:

當背景不存在該應用的任何程序或者服務時,使用者點選icon圖示啟動,我們稱之為冷啟動。

熱啟動

當背景存在該應用的程序或者服務時,使用者點選icon圖示啟動,我們稱之為熱啟動。

一般是使用者按了home鍵回到桌面,或者傳回鍵沒有殺程序,或者app本身做了程序重新開機的機制。

啟動組成時間

我們主要優化冷啟動時間,隻要冷啟動時間優化了,熱啟動其實也跟着優化了。

冷啟動時間分布如下:

application啟動時間+歡迎頁停留時間

按使用者體驗的啟動時間應該是:

application啟動時間+歡迎頁停留時間+進入首頁後顯示主題的話時間;

三、優化點

1、application的啟動優化-兵家必争之地;

application啟動會經過attachbasecontext-->oncreate;

這兩個方法不執行完是不會出現lanucher頁面的;是以使用者回報點選圖檔後,要過一會才出現歡迎頁的原因以下幾個:

1、這兩個方法太過費時導緻的。

2、application的theme被設定會透明的(系統一般預設有個白色或者黑色的)

3、對啟動頁不要做自定義動畫,效果沒有原聲的好,會有一點點影響。

attachbasecontext優化

這個方法在沒有multidex的app中或者沒有特殊業務的app中一般是不用重寫的,但是由于業務需要,我們的app需要內建multidex,導緻我們需要在此方法裡進行multidex.install操作,這個操作其實是耗時的,沒辦法優化,但是也不能讓使用者傻等.

(1)優化初次啟動

我們知道5.0以下初次安裝啟動需要進行dexopt的過程,這個過程是非常耗時的,在一些比較低端的機子上甚至能到達20秒,而且隻能在主ui線程進行,如果我們直接執行install的話,很有可能出現anr,黑屏,等各種非常不好的體驗,怎麼辦呢,我們可以繞過我們的主程序: 我們開啟一個新的程序用于install操作,并彈出一個歡迎頁;然後再我們的主線程一直檢測是否安裝完成,逾時時間設定為30秒;完成之後彈出主程序的歡迎頁面(注意:為了讓使用者無感覺,這兩個頁面必須一模一樣,且中間不能用過渡動畫)。經過實踐:基本上這套方案可以适用所有目前相容的機型。

(2)application theme建議設定為透明的(處于使用者體驗的考慮)

oncreate優化

每次application啟動或者重新開機的時候都會觸發oncreate;如果這個方法耗時超過500ms的話,你可以很明顯的感受到點選icon之後,歡迎頁不會立刻展示出來。

然而不幸的是,很多第三方的元件,如友盟,百川等等都需要在此進行初始化,原因是防止程序被回收之後他們還有機會進行重新初始化而不影響業務。

原因上我們可以接受,但一旦初始化耗費時間多少完全無法控制,完全看第三方“良心”了,但即使在 我們既無法改變第三方初始化速度慢的問題,也不能将其從application移除的情況下,我們依然要優化啟動速度,因為使用者體驗是在太重要。

迎難而上吧!

優化思路:最大的優化思路就是oncreate什麼都不執行,先讓歡迎頁彈窗出來;這個想法初步很簡單,也很好實作,然而存在幾個問題:

(1)程序被回收重新開機後,如何重新初始化?

(2)通知欄推送後,進入到目的頁面,如何防止因為沒初始化導緻的閃退或者功能異常?

(3)application oncreate什麼都不做,那初始化放在哪裡做呢;

隻要這兩個問題解決了,基本上application的優化就算完成了,怎麼解決呢,我們采用了下面的辦法 我們在application隻幹了一件事,而且幾乎不費時,他就是:監聽頁面的生命周期:

這個方法可以讓我們監聽所有頁面的生命周期,包括啟動,可見,銷毀等等,而啟動的時候android本身帶了一個參數 public void onactivitycreated(activity activity, bundle savedinstancestate);中的bundle,如果bundle不為空,說明是回收回來的,我們可以在這裡進行重新初始化,而不影響其他功能;是以(1)(2)問題迎刃而解; 關于(3)的問題是正常流程問題,如果放在歡迎頁初始化,是不妥的,并不是所有的入口都走歡迎頁; 是以我們在application接收了一個初始化的事件,隻要收到這個事件,就可以進行初始化,初始化完了之後,再發出初始化完成的通知; (其實這一步是為了優化歡迎頁做的準備,繼續往下看。)

application通過以上幾步優化之後,就隻剩下5.0以下dexopt和multidex.install消耗的時間優化的,要做到不執行multi.install多個dex,隻能自己動态實作dex的加載,也就是插件化,還有一段很長的路要走,繼續往下說。

2、啟動頁啟動優化-使用者可見的第一感覺

application優化完了以後,就會執行啟動頁的oncreate,我們發現oncreate一旦耗時,也會導緻啟動頁有一順氣的卡頓,精益求精,我們把啟動頁的啟動邏輯延遲初始化并通知application進行初始化,然後等待application初始化完成的事件之後,繼續往下走,知道進入首頁; 啟動也的優化邏輯比較簡單,隻是純業務的上的調整。

3、首頁優化

主要優化oncreate即可。把可以放線程初始化的都放到線程裡去。

經過以上幾步優化之後,我們發現啟動速度有了非常明顯的提示,其實大部分的時候都花在了業務的整理和application啟動的優化上邊,比較容易出bug的地方是我們相當于改變了應該在appliation oncreate初始化方式,由于有些元件初始化是異步的,還是可能出現初始化未完成就被使用的情況,這需要業務上進行相關的處理。貼一組優化後的資料,效果很理想。

優化前:

優化後:

總的來說,對于一個比較大型的app的啟動邏輯還是蠻複雜的,有必要的話都需要整理并優化一下,歡迎大家吐槽,共勉。

繼續閱讀