Android 效能優化系列 — 04 使用 StrictMode 找出在主執行緒的異常請求

Evan Chen

--

Photo by Marianna Lutkova on Unsplash

當 App 在主執行緒長時間阻塞就會發生 ANR。如果這個阻塞的只發生了很短的 1 秒,雖然不會 ANR,但其實也不是使用者可以接受的。正常的 UI 回應速度應該在 0.1~0.2秒之間。這篇就要來介紹使用 StrictMode 來幫助我們找到這些在主執行緒的異常操作。

StrictMode 可以為你偵測是否在主執行緒執行了網路請求檔案存取。使用 StrictMode 的方式是在 ActivityApplicationonCreate 加入下方程式碼來啟動 StrictMode。

StrictMode.setThreadPolicy(
StrictMode.ThreadPolicy.Builder()
.detectDiskReads() //偵測檔案讀取
.detectDiskWrites() //偵測檔案寫入
.detectNetwork() //偵測網路請求
.penaltyFlashScreen() //違規的反應方式
.build()
)

StrictMode 的運作機制為:

  1. 偵測異常行為
  2. 通知異常

偵測異常行為

你可以分別設定需要偵測什麼樣的異常行為:

detectDiskReads() 偵測檔案讀取

detectDiskWrites() 偵測檔案寫入

detectNetwork() 偵測網路請求

detectAll() 偵測所有的異常行為

異常的通知方式

在 StrictMode 偵測到違反規則時,可以選擇以下幾個反應方式:

penaltyLog(): 寫入Log

penaltyDeath(): 讓App閃退

penaltyDialog(): 顯示Dialog

penaltyDeathOnNetwork(): 如果是網路請求就讓閃退

penaltyFlashScreen(): 螢幕會閃一下

範例:在主執行緒執行寫入檔案工作

我們來實際寫一個在主執行緒存取檔案的例子,透過 SharedPreferences 來寫入一筆資料。

binding.saveData.setOnClickListener {
//直在接主執行緒寫入資料
saveData()
}
private fun saveData() {
val pref = getSharedPreferences("StrictModeSample", MODE_PRIVATE)
pref.edit()
.putString("data", "data")
.apply()
}

這段程式碼直接執行就會因為 detectDiskWrites 的設定而被 StrictMode 判定為異常。接著如果通知方式設定為 penaltyLog,則會顯示 log 如下:

StrictMode policy violation; ~duration=50 ms: android.os.strictmode.DiskWriteViolation

通知方式設定為 penaltyDialog 則會彈出警告視窗。

通知方式設定為 penaltyFlashScreen 則會讓畫面閃一下紅框。

StrictMode 異常的處理方式

最後,StrictMode 並不是一種安全機制,不能保證找到所有的網路請求、磁碟存取。例如在 JNI 的網路請求或磁碟存取就不一定會觸發。它的主要功能是讓你找出潛在的問題。但也不是每個 StrictMode 找出的問題都要修復它,例如這裡用的範例 sharedpreference 是以一對 Key 與 Value 的方式來儲存資料,雖然也是檔案儲存違反了StrictMode的規定,但實際上它的存取速度是很快的。一般為了方便我們還是會在主執行緒來直接執行。最後,也請記得只在 debug 模式開啟 StrictMode ,不要在 release 模式開啟,以免影響使用者正常操作。

參考:
https://developer.android.com/reference/android/os/StrictMode

下一篇:縮短 App 的啟動時間

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

No responses yet

Write a response