<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
ANR(Application Not Response)應用程式未響應,當主執行緒被阻塞時,就會彈出如下彈窗
要麼關閉當前app,要麼就等待,其實這個時候沒有挽救的措施,選擇等待最終的結果也是ANR,最終都需要殺掉應用程序,我們看下紀錄檔,原因是Input dispatching timed out,點選事件處理超時導致ANR。
2022-08-27 16:11:53.168 2057-2080/system_process E/ActivityManager: ANR in com.lay.image_process (com.lay.image_process/.MainActivity) PID: 31848 Reason: Input dispatching timed out (Waiting to send non-key event because the touched window has not finished processing certain input events that were delivered to it over 500.0ms ago. Wait queue length: 6. Wait queue head age: 5525.3ms.)
其實相對於其他的錯誤,ANR比較棘手在於,沒有崩潰紀錄檔,定位問題比較困難,而且ANR是必須要解決的問題,這個使用者體驗極差,因此本章的核心在於攻堅ANR問題。
從上面的紀錄檔中,我們看到造成ANR的原因是Input dispatching timed out,那麼除此之外,還有什麼其他的錯誤。
input事件在5s之內沒有處理,產生ANR;這種異常是比較常見的問題,常發生在點選事件處理中,logcat的關鍵字就是Input dispatching timed out
這裡需要說明一點,Input事件導致ANR跟下面幾種不同的是,看下面的程式碼,點選按鈕5s後,才彈出toast,這種情況下會發生ANR嗎?
btnSend.setOnClickListener { Thread.sleep(5 * 1000) ToastUtils.setText(this) }
我們可以在私下測試一下,其實是不會的,如果使用者後續沒有繼續輸入事件,那麼就不會產生ANR
class MyBroadCast : BroadcastReceiver(){ override fun onReceive(context: Context?, intent: Intent?) { //TODO 接收廣播 } }
我們在使用廣播接收器接收廣播時,需要重寫BroadcastReceiver的onReceive方法,當前方法是在主執行緒中,如果在10s內沒有處理彎沉,就會ANR。
因此,在onReceive方法中不能做耗時操作,如果需要則需要建立新的執行緒。logcat關鍵字是 Timeout of broadcast BroadcastRecord
class MyService : Service(){ override fun onCreate() { super.onCreate() } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { return super.onStartCommand(intent, flags, startId) } override fun onBind(intent: Intent?): IBinder? { TODO("Not yet implemented") } }
同樣,在Service中依然不能做耗時操作,如onCreate、onStartCommand、onBind方法中如果超過20s沒有處理完成,就會ANR。
所以如果需要在服務中執行耗時操作,建議使用IntentService,logcat關鍵字是 Timeout executing service
四大元件最後一個元件,如果ContentProvider在10內沒有處理就會導致ANR,這個元件使用很少,暫時先不分析
綜上所述,如果出現ANR,主要原因就是在主執行緒執行了耗時操作,導致UI執行緒被阻塞發生ANR;那麼在我們的實際專案中,有哪些操作,可能會導致ANR呢?
1. 主執行緒進行頻繁的IO操作
不知道我們還有多少在使用SP儲存的,其實它底層就是通過IO讀寫操作檔案,如果頻繁地在主執行緒進行SP讀寫可能會造成卡頓或者ANR,之前就有過線上的ANR事故,建議大家都是用MMKV,讀寫速度秒殺SP;
除此之外,主執行緒進行網路操作也會導致ANR
2. 多執行緒爭奪資源導致死鎖3. CPU資源耗盡
等等......
如果在我們實際的開發過程中,如果出現ANR,那麼很簡單,開啟logcat視窗就可以檢視,還有一種方式,就是檢視trace紀錄檔,路徑為 /data/anr/xxx
開啟trace紀錄檔,通過這一部分就能猜到具體原因了,就是因為在主執行緒中,響應點選事件時,執行緒進入休眠阻塞
線下出問題對於我們來說永遠都是最簡單的,難的就是線上上出了問題,使用者隔你十萬八千里,該如何處理?
可能很多小夥伴的專案中都整合了bugly,確實bugly是很不錯的線上監控元件,像Crash、ANR都能夠檢測到,但是很多時候,紀錄檔是不全的,堆疊資訊不全就沒法定位問題,bugly可以作為兜底方案,具體的監控方案,我們可以自己實現。
對於線上監控,往往有兩種方式,我這邊先講解第一種,通過FileObserver監聽某個目錄下檔案是否發生變化,這裡不言而喻了,就是/data/anr/xxx,如果當前資料夾中的檔案發生變化,那麼意味著ANR發生了,首先我們先了解一個這個類。
@Deprecated public FileObserver(String path) { this(new File(path)); } /** * Equivalent to FileObserver(file, FileObserver.ALL_EVENTS). */ public FileObserver(@NonNull File file) { this(Arrays.asList(file)); } /** * Equivalent to FileObserver(paths, FileObserver.ALL_EVENTS). * * @param files The files or directories to monitor */ public FileObserver(@NonNull List<File> files) { this(files, ALL_EVENTS); }
我們先看一下其中比較核心的構造方法,FileObserver能夠監聽某個路徑下的檔案、某個檔案或者檔案集合的變化,FileObserver是一個抽象類,那麼我們可以實現它來監聽anr目錄檔案的變化
@IntDef(flag = true, value = { ACCESS, MODIFY, ATTRIB, CLOSE_WRITE, CLOSE_NOWRITE, OPEN, MOVED_FROM, MOVED_TO, CREATE, DELETE, DELETE_SELF, MOVE_SELF })
具體的檔案狀態有以上這些,包括ACCESS(當前檔案被存取了)、MODIFY(當前檔案被修改了)、CREATE(當前檔案被建立了)、DELETE(當前檔案被刪除了)等等
class ANRFileObserver( val anrPath: String ) : FileObserver(anrPath) { override fun onEvent(event: Int, path: String?) { when(event){ ACCESS->{ } MODIFY->{ } DELETE->{ } CREATE->{ } } } }
這裡主要是檢測這4種狀態,當前資料夾下內容有修改時,就將全部的trace檔案上傳到伺服器端進行紀錄檔檢視。
val observer = ANRFileObserver("/data/anr/") observer.startWatching()
但是這裡需要注意的就是,很多高版本的ROM已經不支援當前資料夾的檢視,甚至需要Root,因此此策略暫時不能應用,那麼除此之外,還可以通過WatchDog來監控執行緒狀態,從而判斷是否發生ANR。
從字面意思上看,就是看門狗,其實這個是Android系統中的一種監控機制,當SystemServer程序啟動,呼叫start方法之後,WatchDog也就啟動了run方法
從上面這張圖可以理解WatchDog的原理:首先WatchDog是一個執行緒,每隔5s傳送一個Message訊息到主執行緒的MessageQueue中,主執行緒Looper從訊息佇列中取出Message,如果沒有阻塞,那麼在5s內會執行這個Message任務,就沒有ANR;如果超過5s沒有執行,那麼就有可能出現ANR。
到此這篇關於Android效能優化之ANR問題定位分析的文章就介紹到這了,更多相關Android ANR 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45