App 冷啓動緩慢出現白屏之終極解決方案 — IntentService 高效異步處理

什麼叫作冷啓動

第一次啓動或者被用戶主動殺死app進程,或者被系統主動回收掉,整個app的後臺任務被清理,回到桌面再次點擊app的桌面圖標啓動app。java

特色android

後臺任務所有結束,再次啓動數據庫

固然還有與之對應的熱啓動性能優化

熱啓動bash

用戶點擊返回鍵退推到桌面上,後臺任務沒有被殺死。再次點擊桌面圖標啓動app微信

特色多線程

未清理後臺任務,再次啓動app

app啓動時,每個app都會至少建立一個進程出來,一些啓動多線程任務的會建立出來多個進程。異步

爲何會出現白屏現象

首先咱們要知道當打開一個Activity的時候發生了什麼?ide

  • 在一個Activity打開時,若是該Activity所屬的Application尚未啓動,那麼系統會爲這個Activity建立一個進程
  • 每建立一個進程都會調用一次Application,因此Application的onCreate()方法可能會被調用屢次

  • 在進程的建立和初始化中,勢必會消耗一些時間,在這個時間裏,WindowManager會先加載APP裏的主題樣式裏的窗口背景(windowBackground)做爲預覽元素,而後纔去真正的加載佈局

  • 若是這個時間過長,而默認的背景又是黑色或者白色,這樣會給用戶形成一種錯覺,這個APP很卡,很不流暢,天然也影響了用戶體驗。

效果圖對比較:

啓動過長出現白屏效果:

啓動過長出現白屏效果
啓動過長出現白屏效果

利用IntentService優化後的效果:

利用IntentService優化後的效果
利用IntentService優化後的效果

在application裏作一些耗時的一些邏輯:

耗時操做
耗時操做

利用IntentService進行幫助application邏輯相關的異步處理

application相關處理
application相關處理

MyIntentService:

MyIntentService
MyIntentService

該項目是一個關於GreenDao的一個學習案例

GreenDao的一個學習案例
GreenDao的一個學習案例
:

相關該用例中的demo相關CSDN鏈接:

download.csdn.net/detail/andr…

另外參考了網上的另外2種方式這裏也進行總結一下.

  • 一、將背景圖設置成咱們APP的Logo圖,做爲APP啓動的引導,如今市面上大部分的APP也是這麼作的。
<style name="AppWelcome" parent="AppTheme">
        <item name="android:windowBackground">@mipmap/bg_welcome_start</item>
 </style>複製代碼
  • 二、將背景顏色設置爲透明色,這樣當用戶點擊桌面APP圖片的時候,並不會"當即"進入APP,並且在桌面上停留一會,其實這時候APP已是啓動的了,只是咱們心機的把Theme裏的windowBackground的顏色設置成透明的,強行把鍋甩給了手機應用廠商(手機反應太慢了啦,哈哈),其實如今微信也是這樣作的
<style name="Appwelcome" parent="android:Theme.Translucent.NoTitleBar.Fullscreen"/>複製代碼

透明化這種作法須要注意的一點,若是直接把Theme引入Activity,在運行的時候可能會出現以下異常:

java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.

這個是由於使用了不兼容的Theme,例如我這裏的Activity繼承了AppCompatActivity,解決方案很簡單:

  • 一、讓其Activity集成Activity而不要集成兼容性的AppCompatActivity
  • 二、在onCreate()方法裏的super.onCreate(savedInstanceState)以前設置咱們原來APP的Theme
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
            setTheme(R.style.AppTheme);
            super.onCreate(savedInstanceState);
    }
}複製代碼

最後別忘了兩種方式都要在 咱們都須要將Theme引入對應的Activity

<activity
            android:name=".app.main.MainActivity"
            android:theme="@style/AppWelcome"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>複製代碼

IntentService:異步處理服務,新開一個線程:handlerThread在線程中發消息,而後接受處理完成後,會清理線程,而且關掉服務。

IntentService有如下特色:

  • 它建立了一個獨立的工做線程來處理全部的經過onStartCommand()傳遞給服務的intents。

  • 建立了一個工做隊列,來逐個發送intent給onHandleIntent()。

  • 不須要主動調用stopSelft()來結束服務。由於,在全部的intent被處理完後,系統會自動關閉服務。

  • 默認實現的onBind()返回null

  • 默認實現的onStartCommand()的目的是將intent插入到工做隊列中

此次主要是針對於APP第一次啓動過長 出現白屏的解決方案.

如何避免app啓動時間過長呢?

  • 一、不要讓Application參與業務的操做

  • 二、不要在APPlication進行耗時操做,好比有些開發者會在本身的APP裏一系列文件夾或文件(好比我本身),這些I/O操做應該放到"確實該使用的時候再去建立"亦或者是數據庫的一些操做。

  • 三、不要以靜態變量的方式在Application中保存數據等。

另外性能分析工具請參考:

BlockCannery-一個強大的Android程序調試工具,輕鬆幫你找出卡頓

性能優化篇:

Android性能優化 (1)—— 內存溢出和內存泄漏的介紹

相信本身,沒有作不到的,只有想不到的

若是你以爲此文對您有所幫助,歡迎入羣 QQ交流羣 :232203809
微信公衆號:終端研發部

技術+職場
技術+職場
相關文章
相關標籤/搜索