BroadcastReciver 位於 android.content 包下,主要用於對廣播消息(Intent)的過濾並響應的控件。能夠理解爲全局的監聽器。BroadcastReceiver 自身並不實現圖形用戶界面,可是當它收到某個廣播消息後,BroadcastReceiver 能夠啓動 Activity 做爲響應,或者啓動 Service 服務等等。android
-廣播分類git
-靜態廣播github
-動態廣播安全
-廣播發送bash
-廣播接收器網絡
-8.0 靜態廣播app
-帶權限的廣播異步
-本地廣播ide
Broadcast(廣播)是Android的四大組件之一,用於進程/線程間通訊。按照不一樣的方式分類有不一樣的歸類
複製代碼
######發送方式ui
1.標準廣播
徹底異步執行的廣播,沒有前後順序,不可被攔截,效率高
2.有序廣播
同步執行的廣播,有前後順序,發送出去的廣播被廣播接收者按照前後順序接收,而且前面的廣播接收器還能夠截斷正在傳遞的廣播,這樣後面的廣播接收器就沒法接收廣播消息了。
######註冊方式
1.靜態廣播
無論應用程序是否處於活動狀態,都會進行監聽。每次觸發都會創建新的 Receiver 對象。
2.動態廣播
代碼中進行註冊,動態註冊的廣播必定要取消註冊才行,一般是在 onDestroy()方法中調用 unregisterReceiver()方法來實現。從開始建立直到其被解除註冊會使用同一個 Receiver,不管這個廣播被觸發幾回。
######定義方式
1.系統廣播
Android 系統中內置了多個系統廣播,每一個系統廣播都具備特定的 IntentFilter,其中主要包括具體的 Action,系統廣播發出後,將被相應的 BroadcastReceiver 接收。系統廣播在系統內部當特定事件發生時,由系統自動發出。
2.自定義廣播
開發者本身定義的廣播
######範圍方式
1.全局廣播
發出的廣播能夠被其餘任意的應用程序接收,或者能夠接收來自其餘任意應用程序的廣播。
2.本地廣播
只能在本應用程序的內部進行傳遞的廣播,廣播接收器也只能接收內部的廣播,不能接受其餘應用程序的廣播。
介紹完廣播按照不一樣方式的不一樣歸類,接下來來說解一下廣播的使用
靜態廣播的註冊是在 AndroidMainfest.xml 中定義的
<receiver android:name=".ui.broadcast.MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<!-- 接收系統開機廣播 -->
<action android:name="android.intent.action.ACTION_BATTERY_LOW" />
<!-- 接收自定義的廣播 -->
<action android:name="com.madreain.broadcast.MyReceiverFilter" />
</intent-filter>
</receiver>
複製代碼
enabled="true"表明可以接受到廣播信息。exported="true"表明可以接收到外部 APK 發送的廣播信息
動態廣播只須要在使用的代碼中註冊
MyReceiver myReceiver = new MyReceiver();
IntentFilter intentFilter = new IntentFilter();
// 系統廣播 action 接受網絡變化
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
// 自定義的 action
intentFilter.addAction(MyReceiver.ACTION);
registerReceiver(myReceiver, intentFilter);
在onDestory方法中註銷廣播
unregisterReceiver(myReceiver);
複製代碼
不管靜態廣播仍是動態廣播,發送廣播的方式都是同樣的
Intent intent = new Intent();
// 自定義的 action
intent.setAction(MyReceiver.ACTION);
sendBroadcast(intent);
複製代碼
廣播的接受,建立廣播接收器來實現廣播的接受
public class MyReceiver extends BroadcastReceiver {
private static final String ACTION = "com.madreain.broadcast.MyReceiverFilter";
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION) ){
//接收固定廣播進行處理
}
}
}
複製代碼
Android8.0 引入了新的廣播接收器限制,所以您應該移除全部爲隱式廣播 Intent 註冊的廣播接收器。將它們留在原位並不會在構建時或運行時令應用失效,但當應用運行在 Android8.0 上時它們不起任何做用。顯式廣播 Intent(只有您的應用能夠響應的 Intent)在 Android8.0 上仍以相同方式工做。這個新增限制有一些例外狀況。如需查看在以 Android 8.0 爲目標平臺的應用中仍然有效的隱式廣播的列表,請參閱隱式廣播例外。
8.0 發送廣播需修改,需設置 ComponetName,ComponetName(「自定義廣播的包名」, 「自定義廣播的路徑」)
Intent intent = new Intent(STATICACTION);
intent.setComponent(new ComponentName("com.madreain.broadcast", "com.madreain.broadcast.MyReceiver"));
sendBroadcast(intent);
複製代碼
在廣播的實際應用中,咱們爲了不別的應用監聽咱們的廣播,或者別人的應用冒充咱們的應用進行發送廣播。咱們在使用中能夠給廣播增長權限來避免這些安全問題
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.madreain">
<!-- 自定義一個本身的權限 -->
<permission android:name="com.madreain.permissions.MY_BROADCAST"/>
<!-- 使用自定義的權限 -->
<uses-permission android:name="com.madreain.permissions.MY_BROADCAST"/>
<application ...>
<!-- 添加權限 -->
<receiver android:name=".ui.broadcast.MyReceiver"
android:permission="com.madreain.broadcast.MY_BROADCAST"
android:enabled="true"
android:exported="true">
<intent-filter>
<!-- 例如:接收自定義的廣播 -->
<action android:name="com.madreain.broadcast.MyReceiverFilter" />
</intent-filter>
</receiver>
</application>
</manifest>
複製代碼
在發送廣播時,咱們也得指定權限,讓具備權限的應用才能接受到此廣播
Intent intent = new Intent();
intent.setAction(MyReceiver.ACTION);
// 發送廣播,添加權限
sendBroadcast(intent, "com.madreain.permissions.MY_BROADCAST");
複製代碼
其實爲了解決 Android 的廣播安全問題,Android 還引入了另外一個 LocalBroadcastManger 類,接下來的本地廣播來介紹
本地廣播用於應用內部傳遞消息,比 BroadcastReceiver 更加高效,它只在應用內部有效,不須要考慮安全問題。本地廣播的建立仍然是繼承 BroadcastReceiver 建立子類,並實現父類的 onReceive() 方法。在註冊、發送、註銷廣播時使用 LocalBroadcastManager 來進行相關操做。
發送廣播
Intent intent = new Intent(MyReceiver.ACTION));
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
複製代碼
接受廣播
MyReceiver myReceiver = new MyReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(MyReceiver.ACTION);
LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, intentFilter);
複製代碼
註銷廣播
LocalBroadcastManager.getInstance(this).unregisterReceiver(myReceiver);
複製代碼
在此推薦一個第三方消息傳遞的庫EventBus,後期文章將把BroadcastReciver和EventBus作對比進行分析