天天看點

Android面試系列冷啟動優化

什麼是冷啟動?

  1. 冷啟動的定義

    冷啟動就是在啟動應用前,系統中沒有該應用的任何程序資訊時候的啟動(第一次打開應用,或者殺死了這個app程序後的啟動)

  2. 冷啟動/熱啟動的差別

    熱啟動定義:使用者使用app傳回鍵退出應用,然後馬上又重新啟動應用。

    差別一:app的程序是否在手機中已經存在了,冷啟動時app的程序并不存在,需要重新建立;熱啟動是App的程序已經存在了,不需要再重新建立。

    差別二:冷啟動因為之前手機中沒有App的程序2,先建立Application類,再建立MainActivity類;熱啟動會從已有的程序來啟動,不會再走Application類,而是直接啟動MainActivity類(注,一個應用重新程序的建立,到新程序的銷毀,MyApplication類隻初始化建立一次,也就是說熱啟動的時候,代碼并不走MyApplication這個類)

  3. 冷啟動時間的計算

    冷啟動的時間值從應用啟動(建立程序)開始計算,到完成視圖的第一次繪制(即第一個Activity内容對使用者可見)為止。

冷啟動流程

  • Zygote程序中fork建立出一個新的程序
  • 建立初始化Application類,建立MainActivity類
  • setContentView布局,判斷DecorView的存在,通過 inflate将View添加到DecorView的mContentParent中(DecorView會和ViewRoot的實作類ViewRootImpl有一個關聯依賴,後面的幾個方法是ViewRootImpl中的),這裡用到了onMeasure/onLayout/onDraw這幾個方法來完成裡面View内容)
  • 當onCreate/onStart/onResume方法走完,Activity的onResume方法,接着會調用Activity的makeVisible(),在該方法中DecorView真正完成了添加顯示到Window中,Activity的視圖能被使用者看到。

冷啟動流程後引起的黑白屏錯覺卡頓問題

  1. 黑白屏錯覺卡頓問題出現的原因

    在冷啟動流程第三步的時候View添加到了mCOntentParent中,但是這時候DecorView并沒有被WindowManager識别,在第四步的makeVisiable()方法中

void makeVisable(){
    if(!mWindowAdded){
        ViewManager wm=getWindowManager();
        wm.addView(mDecor,getWindow.getAttributes());
        mWindowAdded=true;
    }
    mDecor.setVisibility(View.VISIBLE);
}
           

DecorView真正的完成了添加和顯示這兩個過程,但是wm會先加載APP裡的主題樣式裡的視窗背景(windowBackground)作為預覽元素,然後才去真正的加載布局,如果這個時間過長,而預設的背景又是黑色或者白色,這樣會給使用者造成一種錯覺,這個APP很卡,很不流暢會出現黑色或者白色螢幕閃過,自然也影響了使用者體驗。

  1. 黑白屏錯覺卡頓解決辦法

(1)App啟動頁面為圖檔或者是drawable檔案

//style中
<style name="ThemeSplash" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:background">@drawable/login_qdbg_new</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowFullscreen">true</item>
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>
//權限檔案中
      <activity
            android:name=".ui.splash.SplashActivity"
            android:screenOrientation="portrait"
            android:theme="@style/ThemeSplash">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
           

設定設定整個App的style檔案,設定Android:background屬性為圖檔或者是drawable檔案,這樣App在啟動過程中就是顯示的是啟動頁面的圖檔或者是是drawable檔案;

(2)App啟動頁面為Layout檔案

這時候無法為App的style設定background,退而求其次主流的方式是設定白色背景

<item name="android:windowBackground">@color/color_ffffff</item>
           

而這裡的@color/color_ffffff就是我們定義的白色色值,這樣經過處理之後App啟動時就不會出現黑屏的效果了。

如何優化冷啟動的實際

  1. 在Application中的onCreate()方法中減少工作量,第三方sdk有一個懶加載操作判斷使用的時候調用
  2. 不要讓Application參與業務的操作
  3. 不要讓Application進行耗時的操作(io操作大忌)
  4. 不要以靜态變量的方式在Application中儲存資料,靜态變量生命周期和app是一樣,會造成記憶體洩漏,資料安全等問題
  5. 布局/mainThread MainActivity,View層級減少,可以選擇懶加載按需加載;有一些資源的初始化放在子線程中初始化

推薦連結:黑白屏卡頓分析:https://blog.csdn.net/zivensonice/article/details/51691136

繼續閱讀