前言
最終工作中經常碰到廣播超時的問題,于是花精力總結了一番,各位客官請看~
基本概念
普通廣播與有序廣播
- 普通廣播
普通廣播是完全異步的,邏輯上可以在同一時刻被所有匹配的接受者接收到,消息傳遞效率高,缺點是接受者不能將處理結果傳遞給下一個接收者,也無法終止廣播傳播。
普工廣播是并行廣播。 - 有序廣播
有序廣播的接收者們將按照事先生命的優先級依次接收,數越大優先級越高(取值范圍:-1000~10000),優先級可以聲明在<intent-filter android:priority="n".../>,也可以調用IntentFilter對象的setPriority設置。并且接收者可以終止傳播(調用abortBroadcast()方法即可終止),一旦終止后面接收者就無法接受廣播。另外,接受者可以將處理結果存入數據(可通過setResultExtras(Bundle)方法將數據存入Broadcast),當做Broadcast再傳遞給下一級接收者(可通過代碼Bundle bundle = getResultExtras(true)獲取上一級傳遞過來的數據)。
有序廣播是串行廣播。
有序廣播的發送
各個時間點
- enqueueClockTime 一次廣播插入到廣播隊列時的時間點,取System.currentTimeMillis()
- dispatchTime 一次廣播從廣播隊列中被取出,準備開始發送,取SystemClock.uptimeMillis()
- dispatchClockTime 含義同dispatchTime,取System.currentTimeMillis()
- receiverTime 一次廣播中,開始派發給其中每個接收者時的時間點,主要記錄的是有序廣播的情況,取SystemClock.uptimeMillis()。
- finishTime 一次廣播完成時的時間點
每次把廣播發送給一個接受者之后會去檢查當前時間與dispatchTime 時間差是否大于超時時間,大于時就是ANR超時
時序圖
廣播超時時序圖.jpg
從圖中可以看出決定廣播B接受者的廣播接受是否超時,取決于廣播A處理的時間和廣播B處理的時間
超時的原因
- 同一個廣播接收者較多,搶占了后面的接收者允許處理的時間。廣播接受者較多也可能是由于代碼設計不合理,注冊了廣播監聽沒有解注冊有關。
- Binder被耗盡,導致Binder通信時間較長,擠壓了廣播處理的時間
- 廣播接受的onReceive中做了繁重的任務
- 系統資源緊張,CPU處理時間被搶占
優化建議
- 保證廣播監聽的注冊與解注冊成對實現
- 同一個應用對同一個廣播的監聽應該使用同一個監聽者,不應該多處監聽
- 在廣播的onreceive中不應該做繁重的任務