BroadCastReceiver 是 Android 四大組件之一,主要用於接收系統或者 app 發送的廣播事件。android
經過 Android 系統的 Binder 機制實現通訊。複製代碼
徹底異步,邏輯上能夠被任何廣播接收者接收到。優勢是效率較高。缺點是一個接收者不能將處理結果傳遞給下一個接收者,並沒有法終止廣播 intent 的傳播。web
按照被接收者的優先級順序,在被接收者中依次傳播。好比有三個廣播接收者 A,B,C,優先級是 A > B > C。那這個消息先傳給 A,再傳給 B,最後傳給 C。每一個接收者有權終止廣播,好比 B 終止廣播,C 就沒法接收到。此外 A 接收到廣播後能夠對結果對象進行操做,當廣播傳給 B 時,B 能夠從結果對象中取得 A 存入的數據。設計模式
在經過bash
Context.sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler,initialCode, initialData,initialExtras)複製代碼
時咱們能夠指定 resultReceiver 廣播接收者,這個接收者咱們
能夠認爲是最終接收者,一般狀況下若是比他優先級更高的接收者若是沒有終止廣播,那麼他的onReceive會被執行兩次,第一次是正常的按照優先級順序執行,第二次是做爲最終接收者接收。微信
若是比他優先級高的接收者終止了廣播,那麼他依然能接收到廣播。架構
在咱們的項目中常常使用廣播接收者接收系統通知,好比開機啓動、sd 掛載、低電量、外播電話、鎖屏等。app
若是咱們作的是播放器,那麼監聽到用戶鎖屏後咱們應該將咱們的播放之暫停等。異步
在清單文件中註冊廣播接收者稱爲靜態註冊,在代碼中註冊稱爲動態註冊。靜態註冊的廣播接收者只要 app 在系統中運行則一直能夠接收到廣播消息,動態註冊的廣播接收者當註冊的 Activity 或者 Service 銷燬了那麼就接收不到廣播了。ide
在清單文件中進行以下配置測試
<receiver android:name=".BroadcastReceiver1" >
<intent-filter>
<action android:name="android.intent.action.CALL" >
</action>
</intent-filter>
</receiver>複製代碼
動態註冊:在代碼中進行以下注冊
receiver = new BroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(CALL_ACTION);
context.registerReceiver(receiver, intentFilter);複製代碼
a. 廣播接收者的生命週期很是短暫的,在接收到廣播的時候建立,onReceive()方法結束以後銷
毀;
b. 廣播接收者中不要作一些耗時的工做,不然會彈出 Application No Response 錯誤對話框;
c. 最好也不要在廣播接收者中建立子線程作耗時的工做,由於廣播接收者被銷燬後進程就成爲了空進程,很容易被系統殺掉;
d. 耗時的較長的工做最好放在服務中完成;
a. 從 MVC 的角度考慮(應用程序內)其實回答這個問題的時候還能夠這樣問,android 爲何要有那 4 大組件,如今的移動開發模型基本上也是照搬的 web 那一套 MVC 架構,只不過是改了點嫁妝而已。android的四大組件本質上就是爲了實現移動或者說嵌入式設備上的 MVC 架構,它們之間有時候是一種相互依存的關係,有時候又是一種補充關係,引入廣播機制能夠方便幾大組
件的信息和數據交互。
b. 程序間互通消息(例如在本身的應用程序內監聽系統來電)
c. 效率上(參考 UDP 的廣播協議在局域網的方便性)
d. 設計模式上(反轉控制的一種應用,相似監聽者模式)
Intent intent = new Intent(); intent.setType("image/*"); //經過type來讓系統選擇 視頻video/* intent.setAction(Intent.ACTION_GET_CONTENT);複製代碼
好比項目上須要使用廣播進行跨進程通訊,在7.0以前的版本測試都是OK,在7.0上搞死接收不到發送的廣播,關鍵不是這個,關鍵是廣播由於權限問題被拒接,系統不會報錯,也不會拋異常(大概是由於異常被內部捕獲了),最後在輸出的log中進行全局搜索才肯定的問題所在!!!
解決方法其實很簡單,就是在廣播接受者所在的進程聲明一個權限,在廣播的發送者所在的進程內註冊使用該權限,這樣問題就能夠解決了(這種廣播權限問題只存在跨進程靜態註冊廣播的方式上,動態註冊的廣播好像不存在這種問題!!!)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.permissionbroadcastreceiver">
<permission
android:name="com.example.broadcast.permission"
android:protectionLevel="normal" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".PermissionRecevicer"
android:permission="com.example.broadcast.permission">
<intent-filter>
<action android:name="com.example.permissionbroadcastreceiver.message" />
</intent-filter>
</receiver>
</application>
</manifest>複製代碼
廣播接收沒有權限以完美解決!!!
一個強大的AutoLifecycle—讓普通 Java 類自動感知 Activity Lifecycle
微信公衆號:終端研發部