android 性能優化 -- 啓動過程 冷啓動 熱啓動

android 性能優化 -- 啓動過程 冷啓動 熱啓動

1、應用的啓動方式html

  一般來講,啓動方式分爲兩種:冷啓動和熱啓動。android

  一、冷啓動:當啓動應用時,後臺沒有該應用的進程,這時系統會從新建立一個新的進程分配給該應用,這個啓動方式就是冷啓動。shell

  二、熱啓動:當啓動應用時,後臺已有該應用的進程(例:按back鍵、home鍵,應用雖然會退出,可是該應用的進程是依然會保留在後臺,可進入任務列表查看),因此在已有進程的狀況下,這種啓動會從已有的進程中來啓動應用,這個方式叫熱啓動。性能優化

  特色服務器

  一、冷啓動:冷啓動由於系統會從新建立一個新的進程分配給它,因此會先建立和初始化Application類,再建立和初始化MainActivity類(包括一系列的測量、佈局、繪製),最後顯示在界面上。app

  二、熱啓動:熱啓動由於會從已有的進程中來啓動,因此熱啓動就不會走Application這步了,而是直接走MainActivity(包括一系列的測量、佈局、繪製),因此熱啓動的過程只須要建立和初始化一個MainActivity就好了,而沒必要建立和初始化Application,框架

  由於一個應用重新進程的建立到進程的銷燬,Application只會初始化一次。ide

2、應用的啓動過程佈局

  冷啓動啓動流程:當點擊app的啓動圖標時,安卓系統會從Zygote進程中fork建立出一個新的進程分配給該應用,以後會依次建立和初始化Application類、建立MainActivity類、加載主題樣式Theme中的               post

  windowBackground等屬性設置給MainActivity以及配置Activity層級上的一些屬性、再inflate佈局、當onCreate/onStart/onResume方法都走完了後最後才進行contentView的measure/layout/draw顯示在界面上,因此直到這裏,

  應用的第一次啓動纔算完成,這時候咱們看到的界面也就是所說的第一幀。因此,總結一下,應用的啓動流程以下:

  Application的構造器方法——>attachBaseContext()——>onCreate()——>Activity的構造方法——>onCreate()——>配置主題中背景等屬性——>onStart()——>onResume()——>測量佈局繪製顯示在界面上。

  大體流程以下:

  一、點擊桌面圖標,Launcher會啓動程序默認的Acticity,以後再按照程序的邏輯啓動各類Activity

  二、啓動Activity都須要藉助應用程序框架層的ActivityManagerService服務進程(Service也是由ActivityManagerService進程來啓動的);在Android應用程序框架層中,ActivityManagerService是一個很是重要的接口,

  它不但負責啓動Activity和Service,還負責管理Activity和Service。

    Step 1. 不管是經過Launcher來啓動Activity,仍是經過Activity內部調用startActivity接口來啓動新的Activity,都經過Binder進程間通訊進入到ActivityManagerService進程中,而且調用ActivityManagerService.startActivity接口;

    Step 2. ActivityManagerService調用ActivityStack.startActivityMayWait來作準備要啓動的Activity的相關信息;

    Step 3. ActivityStack通知ApplicationThread要進行Activity啓動調度了,這裏的ApplicationThread表明的是調用ActivityManagerService.startActivity接口的進程,對於經過點擊應用程序圖標的情景來講,這個進程就是Launcher了,

    而對於經過在Activity內部調用startActivity的情景來講,這個進程就是這個Activity所在的進程了;

    Step 4. ApplicationThread不執行真正的啓動操做,它經過調用ActivityManagerService.activityPaused接口進入到ActivityManagerService進程中,看看是否須要建立新的進程來啓動Activity;

    Step 5. 對於經過點擊應用程序圖標來啓動Activity的情景來講,ActivityManagerService在這一步中,會調用startProcessLocked來建立一個新的進程,而對於經過在Activity內部調用startActivity來啓動新的Activity來講,這一步是不須要執行的,

    由於新的Activity就在原來的Activity所在的進程中進行啓動;

    Step 6. ActivityManagerServic調用ApplicationThread.scheduleLaunchActivity接口,通知相應的進程執行啓動Activity的操做;

    Step 7. ApplicationThread把這個啓動Activity的操做轉發給ActivityThread,ActivityThread經過ClassLoader導入相應的Activity類,而後把它啓動起來。

 

3、冷啓動過程當中碰到的白屏黑屏以及優化啓動時間

  

  一、白屏問題 :

  android studio升級 2.0以後 加上Instant Run,Instant Run爲了可以讓咱們快速部署代碼,背後實際上是有一套很是複雜的邏輯的,好比要在APK中創建服務器與Android Studio進行通訊,以及代碼差別比對和替換等,在研發過程當中可能出現白屏問題,

  通常release版的程序是不會出現這種現象的;

  若是接下來還會出現白屏問題,能夠查看style文件

1
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> ...... <item name="android:windowIsTranslucent">true</item> <item name="android:windowNoTitle">true</item> </style>

  加入了兩個屬性,windowIsTranslucent和windowNoTitle,將這兩個屬性都設置成true,就可讓程序在初始化的時候窗口是透明的,初始化結束後程序主界面纔會顯示出來,從而也就徹底看不到白屏界面了

 

  二、啓動時間的優化

  先測量activity的啓動時間-------Activity的reportFullyDrawn()方法 

   你就須要調用Activity的reportFullyDrawn()。它將在log裏報告從apk初始化(和前面Displayed的時間是同樣的)到reportFullyDrawn() 方法被調用用了多長時間。

      reportFullyDrawn()方法顯示的log也是相似這樣:

      ActivityManager: Displayed com.Android.myexample/.StartupTiming: +768ms

     在4.4上調用reportFullyDrawn()方法會崩潰(可是log仍是能正常打印),提示須要UPDATE_DEVICE_STATS權限 ,可是這個權限只有系統app才能受權。解決的辦法是這樣調

 
  try{
    reportFullyDrawn();
  }catch(SecurityException e){
  }
  還有一種測量啓動時間的方法也值得一提,那就是screenrecord命令

  首先啓動帶—bugreport選項(它能夠在frames 中添加時間戳-應該是L中的特性)的screenrecord 命令:

  $ adb shell screenrecord --bugreport /sdcard/launch.mp4
  而後點擊app的圖標,等待app顯示,ctrl-C screenrecord, 使用adb pull命令把文件導出到電腦。
  $ adb pull /sdcard/launch.mp4

  如今你能夠打開錄製視頻看看發生了什麼。你須要一個能逐幀查看的視頻播放器(mac上的Quicktime 就能夠,不清楚其它os上什麼播放器這個功能最好使)。如今逐幀播放,注意視頻的上方有一個frame 時間戳。

  一直往前直到你發現app圖標高亮了爲止。這個時候系統已經處理了圖標上的點擊事件,開始啓動app了,記錄下這一幀的時間。繼續播放幀直到你看到了app整個UI的第一幀爲止。根據不一樣狀況(是否有啓動窗口,是否有啓動畫面等等),

  事件和窗口發生的實際順序可能會有不一樣。對於一個簡單的app來講,你會首先見到啓動窗口,而後漸變出app真實的UI。在你看到UI上的任何內容以後,你應該記錄下第一幀,這時app完成了佈局和繪製,準備開始顯示出來了。同時也記錄下這一幀所發生的時間。

  如今把這兩個時間相減 ((UI displayed) - (icon tapped)); 獲得app從點擊到繪製就緒的全部時間。雖然這個時間包含了進程啓動以前的時間,可是至少它能夠用於跟其餘app比較。

  

Android冷啓動時間優化

 

     冷啓動時間是指當用戶點擊你的app那一刻到系統調用Activity.onCreate()之間的時間段。在這個時間段內,WindowManager會先加載app主題樣式中的windowBackground作爲app的預覽元素,而後再真正去加載activity的layout佈局

冷啓動時間優化

  知道了Android冷啓動時間的原理以後,就能夠經過一些小技巧來對冷啓動時間進行優化,從而讓你app加載變得」快「一些(視覺體驗上的快)。咱們可製做一個啓動Activity的背景樣式的.9圖片,而後把這個.9圖片作爲windowBackground。

  

  圖片製做好以後,咱們就能夠用它作爲app冷啓動階段的預覽元素,以下設置:

  • 爲啓動的Activity自定義一個Theme

    1
    2
    3
    <style name="AppTheme.Launcher">
        <item name="android:windowBackground">@drawable/window_background_statusbar_toolbar_tab</item>
    </style>

      

  • 將新的Theme應用到設置到AndroidManifest.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <activity
        android:name=".MainActivity"
        android:theme="@style/AppTheme.Launcher">
      
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

      

  • 因爲給MainActivity設置了一個新的Theme,這樣作會覆蓋原來的Theme,因此在MainActivity中須要設置回原來的Theme

複製代碼
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { // Make sure this line comes before calling super.onCreate().  setTheme(R.style.AppTheme); super.onCreate(savedInstanceState); } }
複製代碼

 

 

 

當你追求卓越的時候,成功會追着你!
相關文章
相關標籤/搜索