從細節處談Android冷啓動優化

本文來自網易雲社區html


Android APP冷啓動優化,對於Android開發同窗而言多是個老生常談的技優了。 之因此花時間寫一篇冷啓動優化的文章:android

  • 我想從另一個角度來講冷啓動優化,如題所述,從細節處談Android冷啓動優化;web

  • 同時也想借這個話題,和你們分享下作一個技優一般的思路、方法論。網絡

本文的思路以下:先以本次雲課堂B版本、C版冷啓動優化爲切入點,闡述如何作冷啓動優化(第1、2、3、四段落)。而後以此爲demo,抽取一般作一個技優/技改的思路、方法論(第五段落)。
app

1、冷啓動定義

引用google的官方定義工具

A cold start refers to an app’s starting from scratch: the system’s process has not, until this start, created the app’s process. Cold starts happen in cases such as your app’s being launched for the first time since the device booted, or since the system killed the app. This type of start presents the greatest challenge in terms of minimizing startup time, because the system and app have more work to do than in the other launch states.
At the beginning of a cold start, the system has three tasks. These tasks are:性能

  • Loading and launching the app.測試

  • Displaying a blank starting window for the app immediately after launch.優化

  • Creating the app process.this

As soon as the system creates the app process, the app process is responsible for the next stages. These stages are:

  • Creating the app object.

  • Launching the main thread.

  • Creating the main activity.

  • Inflating views.

  • Laying out the screen.

  • Performing the initial draw.

以下圖:

 

簡而言之:冷啓動是APP進程未啓動時,用戶啓動APP到啓動Activity顯示的時候,須要消耗的時間。兩大核心消耗時間無非就是Appliction onCreate時間消耗,以及Splash Activity渲染頁面前的時間消耗。

這邊須要澄清一個點是:APP安裝第一次啓動,和APP進程殺掉再從新啓動,啓動的時間是有不同的地方的,這中間有一個MultiDex的過程(attachBaseContext中)。本文只說起一下MultiDex優化的這個點,但不作深刻闡述。

再補充一個點,google的官方文檔定義的是到Launcher Activity的時間,但一般的APP中會有一個splash Activity,因此有時候,咱們的冷啓動定義會稍微修正下,會計算到真正和用戶相關的Activiy,即splash以後的MainActivity。

2、現狀(優化前)

一開始目測,雲課堂Android客戶端大衆版和企業版的冷啓動時間都不是特別理想,表現爲:

  • 雲課堂Android客戶端C版(大衆版)啓動出現白屏,須要等上2,3S會纔出現Splash頁面;

  • 雲課堂Android客戶端B版(企業版)用戶點擊icon,沒有反應,等上2,3s後纔會出現splash頁面。

一個點擊無反應,一個點擊後白屏,都是讓挑剔的用戶很不爽的一件事情。從用戶體驗的角度,而且,一個APP的冷啓動時間是一個APP的第一門面,故決定作下冷啓動優化,消除白屏,點擊無反應的狀況。

3、冷啓動優化過程

3.0、總體思路以下:

 

3.一、數據分析:

對雲課堂C版和B版都作了詳細的數據分析,分析咱們的Application onCreate過程究竟作了哪些事情,哪些事情是必須的,哪些事情是能夠移除的,哪些事情是能夠分段處理的,分析咱們的Splash到Main又經歷了哪些事情。

Application onCreate具體的細節能夠看上圖思惟導圖中的羅列,對這些操做進行了打點,數據採集,把前幾名耗時較多的羅列以下(下圖是C版的,B版相似):

ActivitySplash到Main又作了哪些事情呢?
C版這邊發現了一個重大的問題,代碼中不管什麼狀況下,都會等上至少2s的時間去加載main。這是個歷史遺留問題,這個頁面會有一些網絡請求,本意是最多不超過等待2s,但代碼實現爲至少等待2s。發現這個問題,一開始的心情是喜憂參半,喜的是性能一會兒提高了至少1s以上,憂的是這個邏輯也太大意了,或者也太沒有說服力來講明爲何這樣實現,那咱們App的其它地方是否也存在這種相似的低級邏輯實現,咱們的精品APP建設之路會比較艱辛,咱們的代碼斟酌還須要優化優化,更多細節須要關注,考察。

3.二、具體細節優化:

幾個原則:

  • 初始化過程,按需初始化,不是必須的就日後挪。

  • 避免長時間的同步操做。

  • 用戶操做感知及時性。

1)、用戶操做感知及時性
針對用戶點擊圖標後白屏或者無反應現象:
Android系統在啓動APP的時候,會將第一個啓動的Activity的背景拿出先展現出來,若Activity的window背景沒有設置,那默認就是白屏;若設置了透明,就會點擊後看起來沒有反應。
咱們能夠經過自定義style來解決這個問題,以下:

    <style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
        <item name="android:windowBackground">@drawable/img_splash</item>
    </style>

是否是很是easy?從Android自身原理的一個小細節,就能夠給用戶提高很是大的體驗。

該方法可能會在某些機型下出現黑屏問題,能夠以下優化:
增長一個Activity放入到主dex中,在minifest中聲明成子進程。這個頁面不作任何事情,只是啓動原來的ActivitySplash,至關於啓動主進程。同時在子進程的Appliaction不加載其餘dex和初始化其餘組件。即在attachBaseContext和onCreate中判斷是init進程就直接return掉。至關於在主進程啓動過程當中用一個window遮罩起來。

2)、Application onCreate優化 具體如上圖數據分析圖中的action,無非就是兩個點:

  • 延後;

  • 按需加載。

舉個module按需加載的例子,以前咱們全部module的初始化工做都在application中,優化以後,是須要用到的時候再進行初始化。代碼以下:

優化前:初始化工做都在application,獲取的時候直接獲取。

    public ILiveModule getLiveModule() {
        ILiveModule module = getModule(ModuleType.MLive);        return module;
    }

優化後:按需加載,application中的初始化工做所有刪除。獲取的時候作判空操做。

    public ILiveModule getLiveModule() {
        ILiveModule module = getModule(ModuleType.MLive);        if(null == module){            // 初始化並註冊
            ILiveModuleConfig liveConfig = new LiveConfigImpl();
            LiveModuleDenpendency liveDependency = new LiveModuleDenpendency();
            module = new LiveModuleImpl(liveConfig, liveDependency,
                    liveDependency, liveDependency, liveDependency, liveDependency, liveDependency, liveDependency);
            registerModule(ModuleType.MLive, module);
        }        return module;
    }

3)、Splash頁面跳轉至Main頁面的邏輯優化
如上文中說的歷史遺留問題,修復這個問題,性能一會兒提高了1s+。

4)、別的一些細節點
如:啓動過程可能會用到一些Utils等工具類,某些Utils類中定義了靜態變量,這些靜態變量的初始化有必定的耗時,能夠把靜態變量的初始化移到第一次使用的時候。這樣能夠避免在用到工具類的其餘方法時提早作了不必的初始化。

5)、抓細節
冷啓動的優化是個很是瑣碎的事情,先把大頭去掉,後面就是摳細節,細節處深挖,能節約一點時間算一點,螞蟻小也是肉。

3.三、測試過程:

羅列修改範圍,APP啓動的邏輯都需自測一遍,主進程銷燬後,消息進來後的邏輯等等。

4、冷啓動優化結果

如下是C版的數據比對:


會隨着C版5.5.0上線,B版1.8.3上線。

5、技優思路、方法論

任何一項技術優化,到最後,都是在摳細節,抓住細節處,精益求精,正如網易的Slogan:「以匠心,致創新」。

一個技術優化改造,無非就是這幾步:

  • 1.爲何要作這件事情;

  • 2.這件事情怎麼作;

  • 3.這件事情的結果,帶來的意義。

  • 也是咱們一般在說的3W原則。

在具體作的過程當中,咱們能夠更細化,好比:

  • 咱們現狀是怎麼樣的,目前的現狀會帶來什麼問題,咱們作了會帶來什麼好處;

  • 咱們作這件事情以前,把咱們的標準統一化,你們約定俗成,目標一致,衡量標準一致;

  • 分析現狀的緣由,技術難點,資源問題等;

  • 咱們如何作這件事情,咱們分迭代作這件事情,仍是一次性搞完,咱們如何分工,如何迭代,如何劃分里程碑點;

  • 如何保證質量,不引發線上問題;

  • 具體action後的衡量方式,考覈標準;

  • 結果闡述,歸檔,以及後期你們要遵照的規約等。

不要怕事小,而在於用什麼心作這件事情。

 

原文:從細節處談Android冷啓動優化

網易雲新用戶大禮包:https://www.163yun.com/gift

本文來自網易實踐者社區,經做者韓坤芳受權發佈。

相關文章
相關標籤/搜索