新聞中心
前言
Android 中的每個(gè)應(yīng)用程序都可以對(duì)自己感興趣的廣播進(jìn)行注冊(cè),這樣該程序就只會(huì)接受自己所關(guān)心的廣播內(nèi)容,這些廣播內(nèi)容可能是來(lái)自于系統(tǒng),也可能是來(lái)自于其他應(yīng)用程序的;

Android 提供了一整套的 API,允許應(yīng)用程序自由地發(fā)送和接受廣播
今天我們就來(lái)詳細(xì)介紹下
一. 廣播介紹
1、標(biāo)準(zhǔn)廣播
- 這是一種完全異步執(zhí)行的廣播,在廣播發(fā)出之后,所有的廣播接收器幾乎都會(huì)在同一時(shí)刻接收到這條廣播消息,因此它們之間沒(méi)有任何先后順序可言。接收器不能對(duì)收到的廣播做任何處理,也不能截?cái)鄰V播繼續(xù)傳播;
- 該種類的廣播用sendBroadcast發(fā)送;
2、有序廣播
- 這是一種同步執(zhí)行的廣播,在廣播發(fā)出之后,同一時(shí)刻只會(huì)有一個(gè)廣播接收器能夠收到這條廣播消息,當(dāng)這個(gè)廣播接收器中的邏輯執(zhí)行完畢后,廣播才會(huì)繼續(xù)傳遞;
- 所以此時(shí)的廣播接收器是有先后順序的,優(yōu)先級(jí)高的廣播接收器就可以先收到廣播消息,并且前面的廣播接收器還可以截?cái)嗾趥鬟f的廣播,這樣后面的廣播接收器就無(wú)法收到廣播消息了;
- 該種類的廣播用sendOrderedBroadcast發(fā)送;
3、粘性廣播
- 粘性廣播的特點(diǎn)是Intent會(huì)一直保留到廣播事件結(jié)束,而這種廣播也沒(méi)有所謂的10秒限制,10秒限制是指普通的廣播如果onReceive方法執(zhí)行時(shí)間太長(zhǎng),超過(guò)10秒的時(shí)候系統(tǒng)會(huì)將這個(gè)廣播置為可以被干掉的‘候選人’,一旦系統(tǒng)資源不夠的時(shí)候,就會(huì)干掉這個(gè)廣播而讓它不執(zhí)行。該廣播用sendStickyBroadcast發(fā)送;
- 在Android5.0 & API 21中已經(jīng)失效,所以不建議使用;
二、廣播詳解
Android 內(nèi)置了很多系統(tǒng)級(jí)別的廣播,我們可以在應(yīng)用中通過(guò)監(jiān)聽(tīng)這些廣播來(lái)得到各種系統(tǒng)的狀態(tài)信息。比如手機(jī)開機(jī)后會(huì)發(fā)送一條廣播,電池的電量發(fā)生變化會(huì)發(fā)出一條廣播,時(shí)間或時(shí)區(qū)發(fā)生改變也會(huì)發(fā)出一條廣播等等;
注冊(cè)廣播方式一般有兩種:
動(dòng)態(tài)注冊(cè)在代碼中注冊(cè);
靜態(tài)注冊(cè)在 AndroidManifest.xml 中注冊(cè)
1、靜態(tài)注冊(cè)
一般為常駐廣播,在AndroidManifest.xml里通過(guò) 標(biāo)簽聲明
intent過(guò)濾器里指定的是接收器訂閱的action;
2、動(dòng)態(tài)注冊(cè)
非常駐廣播,在使用時(shí)注冊(cè),用完及時(shí)銷毀;
- BroadcastReceiver br = new MyBroadcastReceiver();
- IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
- filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
- this.registerReceiver(br, filter);
記得及時(shí)注銷,以免內(nèi)存泄漏;
- @Override
- protected void onDestroy() {
- super.onDestroy();
- unregisterReceiver(receiver);
- }
3、自定義廣播
注冊(cè)廣播
- android:name=".test.MyBroadcastReceiver"
- android:enabled="true"
- android:exported="true">
- public class MyBroadcastReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- Toast.makeText(context,"發(fā)送標(biāo)準(zhǔn)廣播",Toast.LENGTH_LONG).show();
- }
- }
- Intent intent = new Intent("com.test.test");
- sendBroadcast(intent);
- //發(fā)送有序廣播
- Intent intent = new Intent("com.test.test");
- sendOrderedBroadcast(intent,null);
4、本地廣播
我們發(fā)送和接受的廣播全部屬于系統(tǒng)全局廣播,即發(fā)出的廣播可以被其它任何應(yīng)用程序接收到,并且我們也可以接受來(lái)自于其它任何應(yīng)用程序的廣播;
為了解決廣播安全性問(wèn)題,Android 引入了一套本地廣播機(jī)制,使用這個(gè)機(jī)制發(fā)出的廣播只能在應(yīng)用程序內(nèi)部進(jìn)行傳遞,并且廣播接受器也只能接受來(lái)自本應(yīng)用程序發(fā)出的廣播,這樣所有的安全性問(wèn)題就都不存在了;
初始化廣播:
- private LocalBroadcastManager localBroadcastManager;
- private void init() {
- //獲取實(shí)例
- localBroadcastManager = LocalBroadcastManager.getInstance(this);
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction("om.test.LOCAL_BROADCAST");
- LocalReceiver localReceiver = new LocalReceiver();
- localBroadcastManager.registerReceiver(localReceiver, intentFilter);
- }
- Intent intent = new Intent("om.test.LOCAL_BROADCAST");
- localBroadcastManager.sendBroadcast(intent);
- 定義
- private class LocalReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- Toast.makeText(context, "本地廣播.....", Toast.LENGTH_LONG).show();
- }
- }
優(yōu)點(diǎn):
- 可以明確知道正在發(fā)送的廣播不會(huì)離開我們的程序,因此不必?fù)?dān)心機(jī)密數(shù)據(jù)泄露:
- 其它的程序無(wú)法將廣播發(fā)送到我們程序內(nèi)部,因此不需要擔(dān)心會(huì)有安全漏洞問(wèn)題:
- 發(fā)送本地廣播比發(fā)送系統(tǒng)全局廣播更加高效:
5、帶權(quán)限的標(biāo)準(zhǔn)廣播
發(fā)廣播
當(dāng)調(diào)用sendBroadcast(Intent, String)或sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)時(shí),可以指定權(quán)限參數(shù);
- sendBroadcast(new Intent("com.test"),
- Manifest.permission.SEND_SMS);
要想接收這個(gè)廣播,那么這個(gè)接收的app必須申請(qǐng)?jiān)摍?quán)限
接收廣播
如果在注冊(cè)廣播接收器時(shí)指定了權(quán)限參數(shù)(使用registerReceiver(BroadcastReceiver,IntentFilter,String,Handler)或清單文件中的 里),則只有在清單文件中使用 請(qǐng)求權(quán)限的廣播發(fā)送者才可以將Intent發(fā)送給接收者;
在清單文件中聲明:
- android:permission="android.permission.SEND_SMS">
在注冊(cè)的時(shí)候聲明:
- IntentFilter filter = new IntentFilter("com.test);
- registerReceiver(receiver, filter, Manifest.permission.SEND_SMS, null );
要給它發(fā)消息,那廣播發(fā)送的app就必須得申請(qǐng)獲得相應(yīng)的權(quán)限才行:
總結(jié)
動(dòng)態(tài)注冊(cè)廣播不是常駐型廣播,也就是說(shuō)廣播跟隨Activity的生命周期。注意在Activity結(jié)束前,移除廣播接收器;
靜態(tài)注冊(cè)是常駐型,也就是說(shuō)當(dāng)應(yīng)用程序關(guān)閉后,如果有信息廣播來(lái),程序也會(huì)被系統(tǒng)調(diào)用自動(dòng)運(yùn)行;
當(dāng)廣播為有序廣播時(shí):優(yōu)先級(jí)高的先接收(不分靜態(tài)和動(dòng)態(tài))。同優(yōu)先級(jí)的廣播接收器,動(dòng)態(tài)優(yōu)先于靜態(tài);
同優(yōu)先級(jí)的同類廣播接收器,靜態(tài):先掃描的優(yōu)先于后掃描的,動(dòng)態(tài):先注冊(cè)的優(yōu)先于后注冊(cè)的;
當(dāng)廣播為默認(rèn)廣播時(shí):無(wú)視優(yōu)先級(jí),動(dòng)態(tài)廣播接收器優(yōu)先于靜態(tài)廣播接收器。同優(yōu)先級(jí)的同類廣播接收器,靜態(tài):先掃描的優(yōu)先于后掃描的,動(dòng)態(tài):先注冊(cè)的優(yōu)先于后冊(cè)的;
本文轉(zhuǎn)載自微信公眾號(hào)「Android開發(fā)編程」
網(wǎng)站名稱:詳解 Android 中的廣播機(jī)制
本文路徑:http://www.5511xx.com/article/dhdeehe.html


咨詢
建站咨詢
