Android系統廣播(3)–客戶端廣播處理流程

Android系統廣播(3)–客戶端廣播處理流程

接第二部分由AMS回調客戶端ActivityThread方法處理新廣播,這裏回調兩個方法分別處理靜態註冊接收器和動態註冊接收器。如下圖流程也由此開始:

一、處理動態廣播接收器

1.動態廣播由AMS回調ApplicationThread.scheduleRegisteredReceiver()函數

  • 更新下當前進程狀態。

  • 回調傳入參數IIntentReceiver.performReceive()函數,這個傳入對象是廣播接收器動態註冊時傳入AMS端供AMS回調的Binder對象,真正實現在LoadedApk.ReceiverDispatcher.InnerReceiver中。

2.在LoadedApk.ReceiverDispatcher.InnerReceiver.performReceive()中處理

  • 首先獲取對象LoadedApk.ReceiverDispatcher,這個對象對應一個註冊的BroadcastReceiver並由其分發廣播給對應接收器。

  • 判斷LoadedApk.ReceiverDispatcher對象是否爲空,不爲空直接回調其performReceive()。如果是空代表在收到廣播前該接收器已經反註冊,此時需要通知AMS該廣播處理結束。

3.在LoadedApk.ReceiverDispatcher.performReceive()中處理

  • 構造對象Args繼承PendingResult實現Runnable,覆寫方法run()實現廣播分發邏輯。PendingResult代表一個廣播處理結果,在接收器onReceive()中如果需要執行耗時操作,可以獲取這個對象操作執行完成調用其finish()通知AMS廣播處理結束。

  • 調用Handler發佈這個Args對象等待執行。這裏可以指定不同線程的Handler默認是主線程中執行。

4.在Args.run()中執行

  • 爲intent設置對應類加載器,爲receiver設置pendingResult接着回調其onReseive()方法給開發者。

  • 獲取receiver對應的pendingResult,當調用BroadcastReceiver的goAsync時,會將pendingResult置爲null。這裏不爲null時代表沒有調用,直接回調finish()通知AMS。

5.廣播處理結束調用finish()函數通知AMS

  • 首先判斷該廣播發生給的接收器類型

  • 如果是靜態廣播接收器,等待其對應進程是否存在未完成的work。接着調用sendFinished()函數通知AMS。

  • 如果是動態廣播接收器,則其對應廣播類型必須是有序並且目前還未被反註冊。接着調用sendFinished()函數通知AMS。

  • 最後在sendFinished()函數中根據類型調用不同接口通知AMS廣播已經處理完畢。

這裏體現了非動態無序廣播必須在廣播處理完畢之後通知AMS這樣纔會進行下一次廣播的發送操作。

二、處理靜態廣播接收器

1.靜態廣播有AMS回調ApplicationThread.scheduleReceiver()處理

  • 首先更新進程狀態

  • 新建對象ReceiverData封裝傳入參數,其負類也是PengdingResult,其中type字段是TYPE_COMPONENT。這個字段在廣播處理結束時根據其值調用AMS制定接口。

  • handler發送異步消息攜帶數據

2.異步任務中調用handleReceiver()接着處理

  • 首先獲取靜態接收器的類名,獲取其對應的LoadedApk通過這個對象獲取接收器對應的ClassLoader。

  • 使用對應的ClassLoder反射獲取該靜態廣播接收器的實例,獲取這個靜態接收器對象的Application對象及進而獲取其對應的Context對象。

  • 最後將ReceiverData設置進靜態廣播接收器,然後就可以回調對應的onReceive()方法,執行業務方自己的接受廣播後邏輯。

3.廣播處理結束調用finish()函數通知AMS與上述處理動態廣播步驟5一致。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章