4/20/2015

分析ANR (1)

ANR, Application No Response
對岸稱為 應用無響應
其實就是 軟體不理你
也就是說 app main thread 無法做出反應

通常這時候, 螢幕會秀出這樣的畫面給你看

 

根據官方的說法, 通常會發生這樣的情況都是由於系統判斷你的main thread/UI thread已經過了該做出反應的時限卻仍然沒有做出反應, 因此官方強烈建議避免ANR發生的方法就是請不要什麼事都在main thread上面做, main thread負擔愈少愈好

おすすめ:請善用 AyncTask or Handler 這類方法將你想做的事情開在支線任務

------------------------------------------------------------------------------------------------------------------------------
那麼進入正題
通常ANR發生了以後該怎麼辦?
基本上就是直接調出資料做分析

1. 觀察LogCat 確認ANR發生
2. 抓出 data/anr/traces.txt
3. 針對 traces.txt 進行分析 :找出 Application is not responding 發生位置
4. 確認發生ANR的類型
5. 有譜 --> 回頭確認 code
6. 沒譜 --> 進入 thread analysis 對 stack 抽絲剝繭

因為Android會將ANR的log存在 data/anr/ 下, 因此對開發人員來說算是個福音?
至少跟dump是分開的..某種程度來說, 算是簡單的分類
再來, 從上面的步驟可以知道, ANR的分析從第三步開始
因此, 認識ANR發生的類型極其重要
了解類型之後才能加速分析的過程(知道大概問題出在哪方面), 進一步增加得到答案的成功率, 同時也能防止自己日後做出同樣的事情導致必須分析ANR的苦果

---------------------------------------------------------------------------------------------------------------------------------
那麼到底有哪些型態能導致ANR呢?

前面有提過, ANR是系統判斷你的main thread/UI thread已經過了該做出反應的時限卻仍然沒有做出反應, 也就是你 time out
這句話拆解成專業單位來說就是

系統 (Activity Manager/Window Manager system service) : 在2.3以前應只有
Activity Manager, 不過待確認
判斷你的程式 main thread/UI thread
已經過了該做出反應的時限 (timer) : 時間太多的延伸閱讀可看 Watchdog
卻仍然沒有做出反應 (time out)

而在 Android App 裡能觸發 main thread time out 的類型有
1. KeyDispatchTimeout, time limit 5 sec from Android Official
2. BroadcastTimeout, time limit 10 sec from Android Official
3. ServiceTimeout, time limit 20 sec from Google Search (XD)

從上面的分類可以了解, ANR的起因有很多種可能, 就像你打電話去訂餐廳時, 得到訂位確認前等待的時候有有多種可能情況正在發生, 並不代表真的沒位置, 可能是
還沒處理?(其他線程進行中)
正在處理?(進行中但是超時了)
已經處理?(已經等著feedback可是被block住)
一般來說我認為第一種類種類形是最好處理的, 若是碰上已經處理卻被block住的...通常都要走到stack analysis那一步
----------------------------------------------------------------------------------------------------------------------------------
1. KeyDispatchTimeout
最常發生
官網表示:無法對使用者對app做出任何的輸入動作做出反應
輸入動作:input event, 常見的包含鍵盤輸入, 螢幕觸碰
possible keyword: WindowManager: Input event dispatching timed out sending to com.package.name/com.package.name.app.SomeActivity

遇到這種的請先檢查你的 onCreate(), onResume(), onKeyXxx() 任何有關處理 UI rendering 給 user 的地方

2. BroadcastTimeout
少發生
官網表示:BroadcastReceiver 尚未完成工作
possible keyword:
W/ActivityManager(xx) :  Timeout of broadcast BraodcastRecoder
W/ActivityManager(xx) : Receiver during timeout: Xxxxx

這類型的ANR同樣會顯示更detail的訊息在(包括)這兩句之間

3. ServiceTimeout
少發生
possible keyword:
W/ActivityManager(xx) : Timeout executing service: ServiceRecord
E/ActivityManager(xx): Reason: Executing service com.package.name/com.package.name.app.SomeService

-----------------------------------------------------------------------------------------------------------------------------------
以上是至多到第四步的基本分析
若知道了這些就找到原因, 那真是可喜可賀
若還是不知道原因, 就需要更努力看log了, 從第四步開始看
既然要看log, 當然也要附上log本體才能說明
那麼就留到下一篇吧

沒有留言:

張貼留言