前言
- 本篇主要介紹 廣播的類型垮刹、注冊(cè)和發(fā)送廣播信姓、自定義廣播鸵隧、本地廣播等
正文
一、廣播的類型
標(biāo)準(zhǔn)廣播意推,是一種完全異步執(zhí)行的廣播豆瘫,在廣播發(fā)出之后,幾乎所有的廣播接收器會(huì)在同一時(shí)刻接收到這條廣播菊值,不分先后順序外驱,優(yōu)點(diǎn)是效率高,缺點(diǎn)是在廣播的過程中無法被截?cái)?/p>
有序廣播腻窒,是一種同步執(zhí)行的廣播昵宇,在廣播發(fā)出之后,同一時(shí)刻只有一個(gè)廣播接收器能夠收到這條廣播消息儿子,當(dāng)這個(gè)廣播接收器中的邏輯侄子那個(gè)完畢之后瓦哎,廣播才會(huì)繼續(xù)傳遞,根據(jù)優(yōu)先級(jí)分先后順序,優(yōu)先級(jí)高的可以截?cái)嗯c其相鄰的優(yōu)先級(jí)低的廣播
二杭煎、創(chuàng)建一個(gè)廣播接收者
//只需要寫一個(gè)類繼承自 BroadcastReceiver 即可,收到廣播之后會(huì)走 onReceive 方法
public class MyBroadcastReceriver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//注意此方法中不能做耗時(shí)操作卒落,其作用更多是為了打開某個(gè)組件
}
}
三羡铲、注冊(cè)廣播
第二點(diǎn)只是創(chuàng)建了一個(gè)廣播接收器,具體要接收什么樣的廣播主要是根據(jù)注冊(cè)廣播來決定的儡毕。注冊(cè)廣播分兩種方式也切,各有優(yōu)缺點(diǎn),分別為 動(dòng)態(tài)注冊(cè)和靜態(tài)注冊(cè)
3.1 動(dòng)態(tài)注冊(cè)腰湾,
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
MyBroadcastReceriver myBroadcastReceriver = new MyBroadcastReceriver();
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.NEW_OUTGOING_CALL");
registerReceiver(myBroadcastReceriver,filter);
如上所示雷恃,動(dòng)態(tài)注冊(cè)了一個(gè)監(jiān)聽外撥電話的廣播,但是要注意费坊,動(dòng)態(tài)注冊(cè)廣播一定要取消注冊(cè)倒槐,一般是在 onDestroy 方法中 調(diào)用 unregisterReceiver(myBroadcastReceriver); 來取消注冊(cè)
動(dòng)態(tài)注冊(cè)可以自由地控制注冊(cè)和取消,比較靈活附井,但是有一個(gè)前提是程序運(yùn)行之后才會(huì)開始接收廣播讨越,如果說讓接收一條手機(jī)開機(jī)的廣播,動(dòng)態(tài)注冊(cè)就不行了永毅,這得需要靜態(tài)注冊(cè)把跨。
3.2 靜態(tài)注冊(cè)
就拿注冊(cè)一個(gè)接收開機(jī)啟動(dòng)的廣播為例
- 我們用 AndroidStudio 創(chuàng)建一個(gè)廣播之后,AndroidManifest.xml 中會(huì)添加一個(gè)節(jié)點(diǎn)沼死,如下:
<receiver
android:name="broadcastreceiver.MyReceiver"
android:enabled="true"
android:exported="true">
</receiver>
- 我們需要在這個(gè)節(jié)點(diǎn)下添加一條 action 屬性着逐,來表明接收的是什么樣的廣播,如下:
<receiver
android:name="broadcastreceiver.MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
系統(tǒng)開機(jī)完成之后意蛀,會(huì)發(fā)一條 android.intent.action.BOOT_COMPLETED 廣播耸别,所以我們需要添加這個(gè)廣播
- 監(jiān)聽手機(jī)開機(jī) 還需要添加一條權(quán)限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
- 但是靜態(tài)注冊(cè),不能取消
四浸间、發(fā)送自定義廣播
之前我們接收的廣播都是系統(tǒng)定義好的太雨,而實(shí)際項(xiàng)目中,我們很多情況都需要自定義廣播魁蒜。
自定義廣播也是分兩個(gè)步驟囊扳,注冊(cè)廣播和發(fā)送廣播,注冊(cè)廣播也分兩種兜看,靜態(tài)注冊(cè)和動(dòng)態(tài)注冊(cè)锥咸,跟之前說的完全一樣,只不過是那個(gè) action 由我們自己定義而已
4.1 發(fā)送標(biāo)準(zhǔn)廣播
就拿動(dòng)態(tài)注冊(cè)來說吧
//注冊(cè)
MyBroadcastReceriver myBroadcastReceriver = new MyBroadcastReceriver();
IntentFilter filter = new IntentFilter();
filter.addAction("11111111");
registerReceiver(myBroadcastReceriver,filter);
//發(fā)送
Intent intent = new Intent();
intent.setAction("11111111");
sendBroadcast(intent);
我們創(chuàng)建一個(gè)廣播之后细移,在某個(gè)邏輯下 添加如上代碼搏予,就表明注冊(cè)了一個(gè) action 為 11111111 的廣播,當(dāng)有人發(fā)送這條廣播的時(shí)候弧轧,我們的 MyBroadcastReceriver 就會(huì)收到該廣播雪侥。
4.2 發(fā)送有序廣播
- 相對(duì)于標(biāo)準(zhǔn)廣播來說碗殷,只需要在發(fā)送的時(shí)候呢改變一行代碼即可:
sendBroadcast(intent);
//改為
sendOrderedBroadcast(intent,null);
//第二個(gè)參數(shù)表示一個(gè)與權(quán)限相關(guān)的字符串,我們不需要速缨,傳入 null 即可
4.3 設(shè)置廣播優(yōu)先級(jí)锌妻,需要添加一條屬性,如下所示:
<receiver
android:name="broadcastreceiver.MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter
android:priority="1000"
>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
添加了一條 android:priority="1000" 屬性旬牲,其值的范圍在 -1000 和 1000 之間仿粹,數(shù)值越大,優(yōu)先級(jí)越高
4.3 在有序廣播中截?cái)鄰V播
- 只需要在優(yōu)先級(jí)高的廣播的 onReceive 方法中調(diào)用 abortBroadcast(); 就可截?cái)鄰V播
五原茅、使用本地廣播
之前我們所說的所有廣播都是全局廣播吭历,即發(fā)出的廣播可以被任何應(yīng)用程序接收到,而我們的廣播接收器擂橘,也能接收到來自于其他任何應(yīng)用程序的廣播晌区,特別是我們?cè)诎l(fā)送廣播的時(shí)候攜帶一些重要數(shù)據(jù),這要是被其他人應(yīng)用程序獲取到了通贞,豈不是很不安全契讲,而本地廣播就是為了解決這些問題
本地廣播主要是使用了一個(gè) LocalBroadcastManager 類對(duì)廣播進(jìn)行管理,如下所示:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);
//注冊(cè)廣播
MyBroadcastReceriver myBroadcastReceriver = new MyBroadcastReceriver();
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.NEW_OUTGOING_CALL");
localBroadcastManager.registerReceiver(myBroadcastReceriver,filter);
//發(fā)送廣播
Intent intent = new Intent();
intent.setAction("11111111");
localBroadcastManager.sendBroadcast(intent);
- 本地廣播除了之前的優(yōu)點(diǎn)之外滑频,還有一條就是比全局廣播更加高效