目錄
- 1. 廣播接收器是什麼
-
- 1.1 廣播
- 1.2 廣播接收器
- 2. 廣播的實作原理
-
- 2.1 廣播的設計模式和模型
- 2.2 廣播的實作流程
- 3. 廣播的基本用法
-
- 3.1 建立BroadcastReceiver
- 3.2 注冊BroadcastReceiver
-
- 3.2.1靜态注冊(7.0之後部分情況已不可用)
- 3.2.2動态注冊
- 3.3 BroadcastSender向AMS發送廣播
-
- 3.3.1 如何發送廣播
- 3.3.2 廣播的類型
1. 廣播接收器是什麼
1.1 廣播
在認識廣播接收器(
BroadcastReceiver
)之前,先了解一下什麼是廣播(
Broadcast
)。
Broadcast
是一種廣泛應用在應用程式之間傳輸資訊的機制,分為廣播發送器和廣播接收器。Android提供了一套完整的API,允許應用之間自由地發送和接收廣播。
1.2 廣播接收器
廣播接收器(即
BroadcastReceiver
)是Android四大元件之一,屬于
消息型元件
,是一個全局的監聽器,用于接收系統和應用發送的廣播,并作出響應。
BroadcastReceiver
不僅可以在
AndroidManifest.xml
中
靜态注冊
,也可以
動态注冊
(動态注冊的廣播需要在應用啟動後才能進行注冊并接收廣播)。跟
Activity
類似的,
BroadcastReceiver
需要借助
Intent
發送廣播。
了解完基本概念,接下來讓我們探究一下廣播的實作原理吧。
2. 廣播的實作原理
探究廣播實作原理,我們先從廣播的
設計模式
出發,再探究它的具體
實作流程
。
2.1 廣播的設計模式和模型
Android中的廣播使用的是
設計模式
中的
觀察者模式
,
模型
為
基于消息的釋出/訂閱事件模型
。
從
設計模式
來看,廣播的發送器和接收器極大程度的解耦,使得系統友善內建,容易擴充。
從
模型
來看,模型成員的對應關系如下:
- 消息發送者(廣播發送器)
- 消息訂閱者(廣播接收器)
- 消息中心(Activity服務管理(Activity Manager Service),簡稱AMS)
2.2 廣播的實作流程
廣播的實作流程簡圖:
具體流程:
- 廣播接收器(
)通過Binder機制在BroadcastReceiver
中注冊AMS
- 廣播發送器(
)通過Binder機制向BroadcastSender
發送廣播AMS
-
再講廣播發送到符合條件(AMS
/IntentFilter
等)的Permission
相應的消息循環隊列中BroadcastReceiver
-
通過消息循環執行拿到廣播,回調BroadcastReceiver
中的BroadcastReceiver
方法onReceive()
3. 廣播的基本用法
通過上面的學習,我們已經對廣播的實作原理有所了解。這一節我們就來具體了解一下如何使用好廣播。
3.1 建立BroadcastReceiver
建立一個廣播接收器(
BroadcastReceiver
)其實很簡單,分為兩個步驟:
- 建立一個類,并讓它繼承自
類;BroadcastReceiver
- 在這個類中重寫父類的抽象方法
。onReceive()
代碼示範:
//1.建立一個類,并讓它繼承自BroadcastReceiver類
public class MyBroadcastReceiver extends BroadcastReceiver {
//2.重寫父類的抽象方法onReceive()
@Override
public void onReceive(Context context, Intent intent) {
//接收廣播後的邏輯(...)
}
}
原理正如上一節所講到的,
BroadcastReceiver
接收到廣播後會自動回調
onReceive()
方法。我們隻需要在
onReceive()
方法中實作具體的邏輯就好了。預設情況下,
BroadcastReceiver
會在
UI線程
中運作,是以不能執行
耗時操作
。
3.2 注冊BroadcastReceiver
BroadcastReceiver
的注冊方式分為
靜态注冊
、
動态注冊
。
接下來我們分别通過兩種方式,試着注冊
BroadcastReceiver
。
3.2.1靜态注冊(7.0之後部分情況已不可用)
在首次啟動APP時,系統會
自動執行個體化
靜态注冊的類,并注冊到系統中。
注冊方式:在
AndroidManifest.xml
中通過
receiver
标簽注冊,并根據相應的監聽内容在
intent-filter
中添加相應的
action
:
<receiver
android:name=".MyBroadcastReceiver"
android:enabled="true"//表示啟用這個廣播接收器
android:exported="true">//表示允許這個廣播接收器接收本程式以外的廣播
<intent-filter>
//用于接收網絡狀态改變時發出的廣播
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>
最後别忘了根據相應的監聽内容,添加相應的
權限
:
3.2.2動态注冊
注冊方式:在代碼中調用
Context.registerReceiver()
方法:
public class MainActivity extends AppCompatActivity {
private MyBroadcastReceiver myBroadcastReceiver;
private IntentFilter intentFilter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//1.執行個體化 MyBroadcastReceiver、IntentFilter
myBroadcastReceiver = new MyBroadcastReceiver();
intentFilter = new IntentFilter();
//2.設定myBroadcastReceiver監聽的廣播内容
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
//3.動态注冊myBroadcastReceiver
registerReceiver(myBroadcastReceiver,intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
//4.銷毀myBroadcastReceiver
unregisterReceiver(myBroadcastReceiver);
}
}
3.3 BroadcastSender向AMS發送廣播
介紹完怎麼建立、注冊
BroadcastReceiver
,是不是感覺還缺點什麼呢?沒錯,上面執行個體裡
BroadcastReceiver
接收的是系統廣播,那麼怎麼樣讓
BroadcastReceiver
接收我們自定義的廣播呢?那就涉及到怎樣發送自定義的廣播了。
3.3.1 如何發送廣播
廣播是使用
Intent
來辨別的,是以發送廣播隻需兩步:
- 把廣播的值傳入到
中Intent
- BroadcastSender将此廣播的
通過Intent
方法發送出去sendBroadcast()
代碼示範:
Intent intent =new Intent("com.macardo.broadcastreceiver.MyBroadcast");
sendBroadcast(intent);
3.3.2 廣播的類型
- 系統廣播(
)System Broadcast
-
是Android中内置的廣播,手機的基本操作都擁有一個廣播。每個系統廣播都擁有指定的System Broadcast
和intent-filter
。action
- 使用
時,隻需要在注冊廣播接收器時指定相關操作的System Broadcast
即可,不需要手動發送廣播,當執行相關操作時會自動執行action
。System Broadcast
- 普通廣播(
)Normal Broadcast
- 開發者自己定義Intent的廣播,發送廣播:
Intent intent =new Intent("com.macardo.broadcastreceiver.MyBroadcast");
sendBroadcast(intent);
- 當注冊的
中的BroadcastReceiver
與發送的廣播中的action
相同時就接收上述廣播action
- 有序廣播(
)Ordered Broadcast
- 發送有序廣播:
//發送有序廣播
//參數1:intent
//參數2:與權限相關的字元串
sendOrderedBroadcast(intent,null);
- 發送的廣播按照
的優先級接收BroadcastReceiver
//方式1.在AndroidManifest.xml檔案中設定優先級
<intent-filter android:priority="1000">
<action android:name="..."/>
</intent-filter>
//方式2.代碼中設定優先級
intentFilter.setPriority(1000);
- 先接收廣播的
可以對廣播進行截斷或修改,之後接收該廣播的BroadcastReceiver
不再接收到次廣播或接收到被修改的廣播BroadcastReceiver
//截斷廣播,在onReceive()方法中調用
abortBroadcast();
- App應用内廣播(
)Local Broadcast
- 使用
的情況:因為Local Broadcast
對于有exported
情況下預設值為intent-filter
,是以Android中的廣播可以跨應用進行通訊。那麼如果其他App發送的廣播與目前App中的廣播接收器的true
相同時,目前App将接受廣播并處理;如果其他App注冊與目前App一緻的action
用于接收廣播,擷取廣播具體資訊,會出現安全性、效率性的問題。intent-filter
- 使用方法:通過
方法擷取一個LocalBroadcastManager.getInstance(this)
執行個體,然後用LocalBroadcastManager
提供的LocalBroadcastManager
和registerReceiver()
方法來動态注冊和取消接收器以及unregisterReceiver()
方法發送本地廣播sendBroadcast()
代碼示範:
public class MainActivity extends AppCompatActivity {
private MyBroadcastReceiver myBroadcastReceiver;
private IntentFilter intentFilter;
private LocalBroadcastManager localBroadcastManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//1.執行個體化 MyBroadcastReceiver、IntentFilter
myBroadcastReceiver = new MyBroadcastReceiver();
intentFilter = new IntentFilter();
//2.執行個體化LocalBroadcastManager
localBroadcastManager = LocalBroadcastManager.getInstance(this);
//3.設定myBroadcastReceiver監聽的廣播内容
intentFilter.addAction("com.macardo.broadcastreceiver.MyBroadcast");
//4.調用LocalBroadcastManager單一執行個體的registerReceiver()方法進行動态注冊
localBroadcastManager.registerReceiver(myBroadcastReceiver,intentFilter);
Button button =findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent =new Intent("com.macardo.broadcastreceiver.MyBroadcast");
//發送App應用内廣播
localBroadcastManager.sendBroadcast(intent);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
//5.銷毀myBroadcastReceiver
localBroadcastManager.unregisterReceiver(myBroadcastReceiver);
}
}
至此,
BroadcastReceiver(廣播接收器)
的基礎知識就講完了,謝謝觀看。
Github項目位址:BroadcastReceiverDemo