Android性能之 ANR 分析解決

ANR全名Application Not Responding, 也就是"應(yīng)用無響應(yīng)". 當(dāng)操作在一段時間內(nèi)系統(tǒng)無法處理時, 系統(tǒng)層面會彈出上圖那樣的ANR對話框.

產(chǎn)生ANR原因

在Android里, App的響應(yīng)能力是由Activity Manager和Window Manager系統(tǒng)服務(wù)來監(jiān)控的. 通常在如下兩種情況下會彈出ANR對話框:

  1. 5s內(nèi)無法響應(yīng)用戶輸入事件(例如鍵盤輸入, 觸摸屏幕等).
  2. BroadcastReceiver在10s內(nèi)無法結(jié)束.

造成以上兩種情況的首要原因就是在主線程(UI線程)里面做了太多的阻塞耗時操作, 例如文件讀寫, 數(shù)據(jù)庫讀寫, 網(wǎng)絡(luò)查詢等等.

如何避免ANR

知道了ANR產(chǎn)生的原因, 那么想要避免ANR, 也就很簡單了, 就一條規(guī)則:

不要在主線程(UI線程)里面做繁重的操作.

可能產(chǎn)生ANR的條件

  1. 普通阻塞導(dǎo)致的ANR
  2. CPU滿負(fù)荷,這時候一般會在 trace中最后一句看到(100%TOTAL: 5.9% user + 4.1% kernel + 89% iowait)
  3. 內(nèi)存原因(其實(shí)內(nèi)存原因有可能會導(dǎo)致ANR, 例如如果由于內(nèi)存泄露, App可使用內(nèi)存所剩無幾, 我們點(diǎn)擊按鈕啟動一個大圖片作為背景的activity, 就可能會產(chǎn)生ANR)

ANR的處理

針對三種不同的情況, 一般的處理情況如下

  1. 主線程阻塞的

開辟單獨(dú)的子線程來處理耗時阻塞事務(wù).

  1. CPU滿負(fù)荷, I/O阻塞的

I/O阻塞一般來說就是文件讀寫或數(shù)據(jù)庫操作執(zhí)行在主線程了, 也可以通過開辟子線程的方式異步執(zhí)行.

  1. 內(nèi)存不夠用的

增大VM內(nèi)存, 使用largeHeap屬性, 排查內(nèi)存泄露(這個在內(nèi)存優(yōu)化那篇細(xì)說吧)等.

知識點(diǎn)

哪些地方是執(zhí)行在主線程的
  1. Activity的所有生命周期回調(diào)都是執(zhí)行在主線程的.
  2. Service默認(rèn)是執(zhí)行在主線程的.
  3. BroadcastReceiver的onReceive回調(diào)是執(zhí)行在主線程的.
  4. 沒有使用子線程的looper的Handler的handleMessage, post(Runnable)是執(zhí)行在主線程的.
  5. AsyncTask的回調(diào)中除了doInBackground, 其他都是執(zhí)行在主線程的.
  6. View的post(Runnable)是執(zhí)行在主線程的.
使用子線程的方式有哪些
  1. 啟Thread方式(繼承Thread、實(shí)現(xiàn)Runnable接口)
  2. 使用AsyncTask
  3. HandlerThread
  4. IntentService
  5. Loader
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容