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

codeGoogle發表於2019-03-01
什麼叫做冷啟動

第一次啟動或者被使用者主動殺死app程式,或者被系統主動回收掉,整個app的後臺任務被清理,回到桌面再次點選app的桌面圖示啟動app。

特點

後臺任務全部結束,再次啟動

當然還有與之對應的熱啟動

熱啟動

使用者點選返回鍵退推到桌面上,後臺任務沒有被殺死。再次點選桌面圖示啟動app

特點

未清理後臺任務,再次啟動

app啟動時,每一個app都會至少建立一個程式出來,一些啟動多執行緒任務的會建立出來多個程式。

為什麼會出現白屏現象

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

  • 在一個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種方式這裡也進行總結一下.

  • 1、將背景圖設定成我們APP的Logo圖,作為APP啟動的引導,現在市面上大部分的APP也是這麼做的。
<style name="AppWelcome" parent="AppTheme">
        <item name="android:windowBackground">@mipmap/bg_welcome_start</item>
 </style>複製程式碼
  • 2、將背景顏色設定為透明色,這樣當使用者點選桌面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,解決方案很簡單:

  • 1、讓其Activity整合Activity而不要整合相容性的AppCompatActivity
  • 2、在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啟動時間過長呢?

  • 1、不要讓Application參與業務的操作

  • 2、不要在APPlication進行耗時操作,比如有些開發者會在自己的APP裡一系列資料夾或檔案(比如我自己),這些I/O操作應該放到"確實該使用的時候再去建立"亦或者是資料庫的一些操作。

  • 3、不要以靜態變數的方式在Application中儲存資料等。

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

BlockCannery-一個強大的Android程式除錯工具,輕鬆幫你找出卡頓

效能優化篇:

Android效能優化 (1)—— 記憶體溢位和記憶體洩漏的介紹

相信自己,沒有做不到的,只有想不到的

如果你覺得此文對您有所幫助,歡迎入群 QQ交流群 :232203809
微信公眾號:終端研發部

技術+職場
技術+職場

相關文章