文章目錄
BoradCastReceiver基礎
簡介
BroadCastReceiver(廣播)是一種廣泛應用在應用程序之間傳輸信息的機制。而BroadCastReceiver(廣播接收器)則是一種用於接收應用或系統所發出的廣播並進行響應的組件。
原理
Android的廣播使用了觀察者模式:基於消息的發佈/訂閱事件模型。
廣播中有三個角色:
1.消息發佈者(廣播發送者);
2.消息訂閱者(廣播接收者);
3.信息中心(AMS:Activity Manager Service);
流程如下:
1.廣播接收者通過Binder機制在AMS處註冊
2.廣播發送者通過binder機制向AMS發生廣播
3.AMS根據已註冊列表,去尋找合適的廣播接收者(尋找規則:IntentFilter/Permission
)
4.AMS將廣播發送至廣播接收者的消息隊列中
5、廣播接收者獲取到廣播,並調用其onReceive()
方法
BroadCastReceiver的使用
創建Receiver
創建一個Receiver類需要繼承自BraodCastReceiver,並實現其onReceive
方法。在onReceive
方法中可能或涉及與其他組件之間的交互,如發送Notification、啓動service等。但由於生命週期較短(10s左右),不要在onReceive
方法中進行耗時操作。
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"接收到自定義廣播",Toast.LENGTH_SHORT).show();
}
}
Receiver的註冊
註冊一共有兩種方法,分別是動態註冊與靜態註冊。兩者最大的區別是,動態註冊的廣播接收器必須在程序運行後才能接收廣播,而靜態註冊的廣播接收器可以一直接收到廣播。(比如手機開啓與關閉想提示用戶就要靜態註冊廣播接收器)。
1.動態註冊
動態註冊首先要創建IntentFilter與Receiver實例,之後通過addAction
向IntentFilter實例添加廣播,最後註冊registerReceiver(receiver,intentFilter)
。需要注意的是,動態註冊的Receiver需要取消註冊,否則會導致內存泄漏。
當前例子是當網絡發送變化時,系統會發出一條android.net.conn.CONNECTIVITY_CHANGE
的廣播,我們選擇動態註冊Receiver來接收廣播。
private IntentFilter intentFilter;
private NetworkChangeReceiver networkChangeReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
networkChangeReceiver = new NetworkChangeReceiver();
registerReceiver(networkChangeReceiver,intentFilter);
}
@Override
protected void onDestroy(){
super.onDestroy();
unregisterReceiver(networkChangeReceiver);
}
2.靜態註冊
靜態註冊是在AndroidManifest中註冊。我們需要在<receiver>
標籤下聲明<intent-filter>
標籤,同時在<intent-filter>
標籤中繼續聲明<action>
標籤,在<action>
標籤中放置要接收的廣播。
<receiver
android:name=".AnotherReciver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.aaa.special"></action>
</intent-filter>
</receiver>
廣播發送者向AMS發送廣播
廣播是用intent標識的,廣播發送者將intent通過sendBroadcast(intent)
將廣播發出。
廣播類型
普通廣播
普通廣播可以包括自定義的廣播與系統廣播。**普通廣播是以一種異步執行的廣播,在發送廣播後,幾乎會同時到達所有的廣播接收器。**普通廣播的工作流程如下:
1.自定義廣播
首先是發送廣播,創建一個intent,設置action(要發送的廣播),之後使用sendBroadcast
發送廣播。
Intent intent = new Intent();
intent.setAction("com.example.aaa.special");
sendBroadcast(intent);
當已經被註冊的Receiver中intent-filter
中的action
與之匹配,則會調用該Receiver的onReceive
方法。
<receiver
android:name=".AnotherReciver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.aaa.special"></action>
</intent-filter>
</receiver>
2.系統廣播
Android中內置了多個系統廣播:只要涉及到手機的基本操作(如開機、網絡狀態變化、拍照等等),都會發出相應的廣播。
我們只需要定義Receiver,並將其註冊(在intentfilter
中使用對應的action
),並等待系統爲我們發送廣播。
有序廣播
有序廣播是以同步的方式執行的廣播,發送廣播後,在同一時刻只有一個廣播接收器能接收廣播,當這個廣播接收器的邏輯執行完畢後,廣播纔會繼續傳播,因此廣播的接收是有順序的,優先級高的廣播接收器會先接收(相同優先級的動態註冊的先接收)。同時,先接受的廣播接收器,可以將廣播截斷,讓後續廣播接收器無法接收;也可以對廣播修改,後續廣播接收器接收的就是更改過的廣播。
有序廣播的發送方式與普通廣播類似,區別在於sendOrderedBroadcast(intent,null)
。
Intent intent = new Intent();
intent.setAction("com.example.aaa.special");
sendOrderedBroadcast(intent,null);
有序廣播是根據廣播接收器的priority
屬性來判斷哪個廣播接收器先接收,因此我們可以爲廣播接收器設置該屬性。
<intent-filter
android:priority="100">
<action android:name="com.example.aaa.special" />
</intent-filter>
本地廣播
之前發出的廣播屬於全局廣播,所有的app都可以接收到,爲了避免衝突和保持安全性。Android引入了一套本地廣播機制,使用這個機制發出的廣播只能夠在應用程序的內部進行傳遞,並且廣播接收器也只能接收本應用程序發出的廣播。
與全局廣播不同的是,Android引入了一個LocalBroadcastManager來管理,並提供了註冊廣播接收器與取消註冊廣播接收器與發送廣播的方法。全局廣播默認使用的是Context的方法。
總結(複習必看)
1.BroadCastReceiver(廣播接收器)是android四大組件之一,通過廣播接收器可以接收系統或應用發出的廣播,並通過onRecieve
方法進行響應。
2.android中廣播的工作原理是觀察者模式,基於消息的訂閱與發送模型。在工作過程中,第一步由廣播接收器在ActivityManagerService處通過Binder機制註冊,第二步廣播發送者會通過Binder機制向AMS發送廣播,第三步由AMS在已註冊的接收器中根據InterFilter/permission
尋找合適的接收器;第四步AMS將廣播發至對應接收器的消息隊列;第五步接收器接收到廣播,並調用自己的onRecieve
方法。
3.廣播接收器的註冊方式有兩種:1.靜態註冊,2.動態註冊。兩種註冊方式的差別在於動態註冊只能在程序運行後才能接收廣播,同時動態註冊後,需要取消註冊。而靜態註冊,可以持續接收廣播,例如可以在手機開機的時候接收到廣播。在代碼上,靜態註冊是在AndroidManifest中註冊,需要在<receive>
標籤下聲明<intentFilter>
標籤,並在<Intentfilter>
標籤下聲明<action>
標籤,將要接收的廣播放入<action>
標籤。而動態註冊則需要創建BroadCastReceiver的實例與IntentFilter的實例,爲IntentFilter添加廣播addAction()
,之後註冊廣播接收器,同時要在onDestory
或onPause
中取消註冊。
//動態註冊
private IntentFilter intentFilter;
private NetworkChangeReceiver networkChangeReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
networkChangeReceiver = new NetworkChangeReceiver();
registerReceiver(networkChangeReceiver,intentFilter);
}
@Override
protected void onDestroy(){
super.onDestroy();
unregisterReceiver(networkChangeReceiver);
}
//靜態註冊
<receiver
android:name=".AnotherReciver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.aaa.special"></action>
</intent-filter>
</receiver>
4.android中有多種廣播,包括普通廣播,系統廣播,有序廣播,本地廣播。
普通廣播和系統廣播都是異步操作的廣播,接收器幾乎會同時接收到廣播。普通廣播是我們自定義的廣播,廣播通過Intent來傳播,可以向intent添加action,並通過sendBroadcast(intent)
發送。系統廣播是系統在涉及基本操作(開關網絡等)時發送的廣播,我們只需要對BroadCastRecevier註冊即可。
有序廣播是同步執行的廣播。廣播接收器接收廣播是有順序的,同一時間只能有一個廣播接收器接收廣播。會根據廣播接收器的priorty
屬性來判斷先到達哪個接收器。先到達的接收器可以將廣播截斷,之後的接收器就無法接收到廣播,或者可以將廣播更改,之後接收器接收到的就是更改過的廣播。
本地廣播是一種只可以在應用內傳播的廣播,它較爲安全也省去衝突。android系統爲用戶提供了**LocalBroadCastManager
類**來幫助接收器註冊、取消註冊,以及自定義廣播後發送廣播。