1. 程式人生 > >安卓廣播超時的原因分析及優化建議

安卓廣播超時的原因分析及優化建議

前言

最終工作中經常碰到廣播超時的問題,於是花精力總結了一番,各位客官請看~

基本概念

普通廣播與有序廣播

  • 普通廣播
    普通廣播是完全非同步的,邏輯上可以在同一時刻被所有匹配的接受者接收到,訊息傳遞效率高,缺點是接受者不能將處理結果傳遞給下一個接收者,也無法終止廣播傳播。
    普工廣播是並行廣播。
  • 有序廣播
    有序廣播的接收者們將按照事先生命的優先順序依次接收,數越大優先順序越高(取值範圍:-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中不應該做繁重的任務