天天看點

冷啟動與熱啟動,AsyncTask,HandlerThread,IntentService,Service 保活,IntentService

目錄

​​說下冷啟動與熱啟動是什麼,差別,如何優化,使用場景等。​​

​​Android 中的線程有那些,原理與各自特點:AsyncTask,HandlerThread,IntentService​​

​​Service 保活​​

​​ IntentService原理分析​​

說下冷啟動與熱啟動是什麼,差別,如何優化,使用場景等。

app冷啟動: 當應用啟動時,背景沒有該應用的程序,這時系統會重新建立一個新的程序配置設定給該應用, 這個啟動方式就叫做冷啟動(背景不存在該應用程序)。冷啟動因為系統會重新建立一個新的程序配置設定給它,是以會先建立和初始化Application類,再建立和初始化MainActivity類(包括一系列的測量、布局、繪制),最後顯示在界面上。

app熱啟動: 當應用已經被打開, 但是被按下傳回鍵、Home鍵等按鍵時回到桌面或者是其他程式的時候,再重新打開該app時, 這個方式叫做熱啟動(背景已經存在該應用程序)。熱啟動因為會從已有的程序中來啟動,是以熱啟動就不會走Application這步了,而是直接走MainActivity(包括一系列的測量、布局、繪制),是以熱啟動的過程隻需要建立和初始化一個MainActivity就行了,而不必建立和初始化Application

冷啟動的流程

當點選app的啟動圖示時,安卓系統會從Zygote程序中fork建立出一個新的程序配置設定給該應用,之後會依次建立和初始化Application類、建立MainActivity類、加載主題樣式Theme中的windowBackground等屬性設定給MainActivity以及配置Activity層級上的一些屬性、再inflate布局、當onCreate/onStart/onResume方法都走完了後最後才進行contentView的measure/layout/draw顯示在界面上

冷啟動的生命周期簡要流程::

Application構造方法 –> attachBaseContext()–>onCreate –>Activity構造方法 –> onCreate() –> 配置主體中的背景等操作 –>onStart() –> onResume() –> 測量、布局、繪制顯示

冷啟動的優化主要是視覺上的優化,解決白屏問題,提高使用者體驗,是以通過上面冷啟動的過程。能做的優化如下:

減少 onCreate()方法的工作量

不要讓 Application 參與業務的操作

不要在 Application 進行耗時操作

不要以靜态變量的方式在 Application 儲存資料

減少布局的複雜度和層級

減少主線程耗時

為什麼冷啟動會有白屏黑屏問題?原因在于加載主題樣式Theme中的windowBackground等屬性設定給MainActivity發生在inflate布局當onCreate/onStart/onResume方法之前,而windowBackground背景被設定成了白色或者黑色,是以我們進入app的第一個界面的時候會造成先白屏或黑屏一下再進入界面。解決思路如下

1.給他設定 windowBackground 背景跟啟動頁的背景相同,如果你的啟動頁是張圖檔那麼可以直接給 windowBackground 這個屬性設定該圖檔那麼就不會有一閃的效果了

<span style="color:#000000"><code><style name=``"Splash_Theme"` `parent=``"@android:style/Theme.NoTitleBar"``>`
    <item name=``"android:windowBackground"``>@drawable/splash_bg</item>`
    <item name=``"android:windowNoTitle"``>``true``</item>`
</style>`
</code></span>      

   <item name=``"android:windowBackground"``>@drawable/splash_bg</item>`

2.采用世面的處理方法,設定背景是透明的,給人一種延遲啟動的感覺。,将背景顔色設定為透明色,這樣當使用者點選桌面APP圖檔的時候,并不會"立即"進入APP,而且在桌面上停留一會,其實這時候APP已經是啟動的了,隻是我們心機的把Theme裡的windowBackground 的顔色設定成透明的,強行把鍋甩給了手機應用廠商(手機反應太慢了啦)

<span style="color:#000000"><code><style name=``"Splash_Theme"` `parent=``"@android:style/Theme.NoTitleBar"``>`
    <item name=``"android:windowIsTranslucent"``>``true``</item>`
    <item name=``"android:windowNoTitle"``>``true``</item>`
</style>`
</code></span>      

3.以上兩種方法是在視覺上顯得更快,但其實隻是一種表象,讓應用啟動的更快,有一種思路,将 Application 中的不必要的初始化動作實作懶加載,比如,在SpashActivity 顯示後再發送消息到 Application,去初始化,這樣可以将初始化的動作放在後邊,縮短應用啟動到使用者看到界面的時間

Android 中的線程有那些,原理與各自特點:AsyncTask,HandlerThread,IntentService

AsyncTask原理:内部是Handler和兩個線程池實作的,Handler用于将線程切換到主線程,兩個線程池一個用于任務的排隊,一個用于執行任務,當AsyncTask執行execute方法時會封裝出一個FutureTask對象,将這個對象加入隊列中,如果此時沒有正在執行的任務,就執行它,執行完成之後繼續執行隊列中下一個任務,執行完成通過Handler将事件發送到主線程。AsyncTask必須在主線程初始化,因為内部的Handler是一個靜态對象,在AsyncTask類加載的時候他就已經被初始化了。在Android3.0開始,execute方法串行執行任務的,一個一個來,3.0之前是并行執行的。如果要在3.0上執行并行任務,可以調用executeOnExecutor方法

HandlerThread原理:繼承自 Thread,start開啟線程後,會在其run方法中會通過Looper 建立消息隊列并開啟消息循環,這個消息隊列運作在子線程中,是以可以将HandlerThread 中的 Looper 執行個體傳遞給一個 Handler,進而保證這個 Handler 的 handleMessage 方法運作在子線程中

IntentService原理:繼承自Service,它的内部封裝了 HandlerThread 和Handler,可以執行耗時任務,同時因為它是一個服務,優先級比普通線程高很多,是以更适合執行一些高優先級的背景任務,HandlerThread底層通過Looper消息隊列實作的,是以它是順序的執行每一個任務。可以通過Intent的方式開啟IntentService,IntentService通過handler将每一個intent加入HandlerThread子線程中的消息隊列,通過looper按順序一個個的取出并執行,執行完成後自動結束自己,不需要開發者手動關閉

IntentService是Service的子類,比普通的Service增加了額外的功能。先看Service本身存在兩個問題:Service不會專門啟動一條單獨的程序,Service與他所在應用位于同一個程序中。

Service也不是專門一條新程序,是以不應該在Service中直接處理耗時的任務。

特點:

IntentService會建立獨立的worker線程來處理所有的Intent請求;

會建立獨立的worker線程來處理onHandleIntent()方法實作的代碼,無需處理多線程的問題;

所有請求處理完成後,IntentService會自動停止,無需調用stopSelf()方法停止Service;

為Service的onBind()提供預設實作,傳回null;

為Service的onStartCommand提供預設實作,将請求Intent添加到隊列中;

Service 保活

1.在 onStartCommand 中傳回 START_STICKY(粘性的)

這種方式并不能保證 Service 不被殺死,隻是提高 Service 被殺死後快速重新開機機率。

2.雙程序守護

為背景常駐 Service 設定守護程序,互相監聽對方的狀态,當監測到對方被殺死後立即重新開機對方 Service 達到守護 service 的目的。

 IntentService原理分析