可能會存在這樣的情況,你寫的**通過了世界上所有的效能測試,但當使用者嘗試使用你的應用程式時,仍然讓使用者感到不爽。應用程式響應不夠靈敏的地方包括——反映遲鈍,掛起或凍結很長時間,或者需要花費很長的時間來處理輸入。
一般說來,如果應用程式不能響應使用者輸入的話,系統會顯示乙個anr。例如,乙個應用程式阻塞在一些i/o操作上(通常是網路訪問),這時,應用程式的主線程就不能再處理使用者的輸入事件。經過一定的時間後,系統認為應用程式已經掛起,並顯示anr來讓使用者選擇殺死應用程式。
相似地,如果你的應用程式花費太多的時間來構建詳細的記憶體結構,或者也許是在遊戲裡花費太多時間來計算下一步移動,這時,系統會認為你的應用程式已經掛起。因此,確保這些計算是高效的往往很重要,但即使是最高效的**仍然需要花費時間來執行。
這篇文章將討論android系統如何判斷乙個應用程式處於無響應狀態,並為保證應用程式的響應性提供嚮導。
1)什麼引發了anr?
在android裡,應用程式的響應性是由activity manager和window manager系統服務監視的。當它監測到以下情況中的乙個時,android就會針對特定的應用程式顯示anr:
乙個anr對話方塊顯示給使用者
2)如何避免anr?
考慮上面的anr定義,讓我們來研究一下為什麼它會在android應用程式裡發生和如何最佳構建應用程式來避免anr。
android應用程式通常是執行在乙個單獨的執行緒(例如,main)裡。這意味著你的應用程式所做的事情如果在主線程裡占用了太長的時間的話,就會引發anr對話方塊,因為你的應用程式並沒有給自己機會來處理輸入事件或者intent廣播。
因此,執行在主線程裡的任何方法都盡可能少做事情。特別是,activity應該在它的關鍵生命週期方法(如oncreate()和onresume())裡盡可能少的去做建立操作。潛在的耗時操作,例如網路或資料庫操作,或者高耗時的計算如改變位圖尺寸,應該在子執行緒裡(或者以資料庫操作為例,通過非同步請求的方式)來完成。然而,不是說你的主線程阻塞在那裡等待子執行緒的完成——也不是呼叫thread.wait()或是thread.sleep()。替代的方法是,主線程應該為子執行緒提供乙個handler,以便完成時能夠提交給主線程。以這種方式設計你的應用程式,將能保證你的主線程保持對輸入的響應性並能避免由於5秒輸入事件的超時引發的anr對話方塊。這種做法應該在其它顯示ui的執行緒裡效仿,因為它們都受相同的超時影響。
intentreceiver執行時間的特殊限制意味著它應該做:在後台裡做小的、瑣碎的工作如儲存設定或者註冊乙個notification。和在主線程裡呼叫的其它方法一樣,應用程式應該避免在broadcastreceiver裡做耗時的操作或計算。但不再是在子執行緒裡做這些任務(因為broadcastreceiver的生命周期短),替代的是,如果響應intent廣播需要執行乙個耗時的動作的話,應用程式應該啟動乙個service。順便提及一句,你也應該避免在intent receiver裡啟動乙個activity,因為它會建立乙個新的畫面,並從當前使用者正在執行的程式上搶奪焦點。如果你的應用程式在響應intent廣播時需要向使用者展示什麼,你應該使用notification manager來實現。
3)增強響應靈敏性
一般來說,在應用程式裡,100到200ms是使用者能感知阻滯的時間閾值。因此,這裡有一些額外的技巧來避免anr,並有助於讓你的應用程式看起來有響應性。
關於android中的ANR
在onupdate中獲取到fields的更新值 final string fields new string 5 fields 0 notifyvalue update,x1 fields 1 notifyvalue update,x2 fields 2 notifyvalue update,x3 ...
Android 中的ANR 問題,響應靈敏性
size large 可能會存在這樣的情況,你寫的 通過了世界上所有的效能測試,但當使用者嘗試使用你的應用程式時,仍然讓使用者感到不爽。應用程式響應不夠靈敏的地方包括 反映遲鈍,掛起或凍結很長時間,或者需要花費很長的時間來處理輸入。一般說來,如果應用程式不能響應使用者輸入的話,系統會顯示乙個anr。...
Android開發中ANR問題出現及解決
第一 什麼會引發anr?在android裡,應用程式的響應性是由activity manager和windowmanager系統服務監視的 當它監測到以下情況中的乙個時,android就會針對特定的應用程式顯示anr 1.在5秒內沒有響應輸入的事件 例如,按鍵按下,螢幕觸控 2.broadcastr...