前言
Linus Benedict Torvalds : RTFSC – Read The Funning Source Code
概括
廣播(Broadcast)是在組件之間傳播數(shù)據(jù)(Intent)的一種機(jī)制琳疏。通過Broadcast發(fā)送者和接收者霍比,并且不需要知道對方存在房官。
使用
Step 1. 創(chuàng)建接收類
創(chuàng)建一個接收類繼承BroadcastReceiver類焚刺,并覆寫onReceive()方法核行。
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {}
}
Step 2. 注冊廣播接收器
1.靜態(tài)注冊
<application >
<receiver
android:name=".MyBroadcastReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.unknow.jason.broadcasttest.MY_BROADCAST"/>
</intent-filter>
</receiver>
</application>
2.動態(tài)注冊
intentFilter = new IntentFilter();
intentFilter.addAction("com.unknow.jason.broadcasttest.MY_BROADCAST");
myBroadcastReceiver = new MyBroadcastReceiver();
registerReceiver(myBroadcastReceiver, intentFilter);
unregisterReceiver(myBroadcastReceiver);
Step 3. 發(fā)送廣播
Intent intent = new Intent("com.unknow.jason.broadcasttest.MY_BROADCAST");
sendBroadcast(intent);
詳細(xì)使用
靜態(tài)注冊字段
字段 | 解釋 |
---|---|
android:banner | A Drawable resource providing an extended graphical banner for its associated item. 一個Drawable資源為其相關(guān)聯(lián)的項目提供擴(kuò)展的圖形橫幅精算。 |
android:description | Descriptive text for the associated data. 為關(guān)聯(lián)數(shù)據(jù)提供描述伯病。 |
android:directBootAware | Indicate if this component is aware of direct boot lifecycle, and can be safely run before the user has entered their credentials (such as a lock pattern or PIN). 指示此組件是否知道直接引導(dǎo)生命周期,并且可以在用戶輸入其憑據(jù)(例如鎖定模式或PIN)之前安全運行明场。 |
android:enabled | Specify whether the receiver is enabled or not (that is, can be instantiated by the system). 指定這個接收者是否被開啟汽摹。是否被系統(tǒng)注冊。 |
android:exported | Flag indicating whether the given application component is available to other applications. 指示給定應(yīng)用程序組件是否可用于其他應(yīng)用程序的標(biāo)志苦锨。 |
android:icon | A Drawable resource providing a graphical representation of its associated item. 一個可繪制的資源逼泣,提供其關(guān)聯(lián)項目的圖形表示。 |
android:label | A user-legible name for the given item. 給定項目的用戶可讀名稱舟舒。 |
android:logo | A Drawable resource providing an extended graphical logo for its associated item. 一個Drawable資源拉庶,為其相關(guān)聯(lián)的項目提供擴(kuò)展的圖形標(biāo)志。 |
android:name | Required name of the class implementing the receiver, deriving from BroadcastReceiver. 實現(xiàn)接收器的類的所需名稱秃励,源自BroadcastReceiver氏仗。 |
android:permission | Specify a permission that a client is required to have in order to use the associated object. 指定客戶機(jī)必須具有的權(quán)限才能使用關(guān)聯(lián)的對象。 |
android:process | Specify a specific process that the associated code is to run in. 指定一個指定的進(jìn)程讓關(guān)聯(lián)的代碼在此上運行夺鲜。 |
android:roundIcon | A Drawable resource providing a graphical representation of its associated item. 一個可繪制的資源皆尔,提供其關(guān)聯(lián)項目的圖形表示。 |
android:singleUser | If set to true, a single instance of this component will run for all users. 如果設(shè)置為true币励,則此組件的單個實例將為所有用戶運行慷蠕。 |
LocalBroadcastManager
Helper to register for and send broadcasts of Intents to local objects within your process.幫助程序注冊和發(fā)送Intents的廣播到您的進(jìn)程中的本地對象。
與使用sendBroadcast(Intent)發(fā)送全局廣播相比食呻,這具有許多優(yōu)點:
- 您知道您正在播送的數(shù)據(jù)不會離開您的應(yīng)用流炕,因此不需要擔(dān)心泄露私人數(shù)據(jù)。
- 其他應(yīng)用程序不可能將這些廣播發(fā)送到您的應(yīng)用程序搁进,因此您不必?fù)?dān)心它們可以利用的安全漏洞浪感。
- 它比通過系統(tǒng)發(fā)送全局廣播更有效。
主要使用方法:
返回值 | 函數(shù) | 解釋 |
---|---|---|
static LocalBroadcastManager | getInstance(Context context) | |
void | registerReceiver(BroadcastReceiver receiver, IntentFilter filter) | Register a receive for any local broadcasts that match the given IntentFilter. |
boolean | sendBroadcast(Intent intent) | Broadcast the given intent to all interested BroadcastReceivers. |
void | sendBroadcastSync(Intent intent) | Like sendBroadcast(Intent), but if there are any receivers for the Intent this function will block and immediately dispatch them before returning. |
void | unregisterReceiver(BroadcastReceiver receiver) | Unregister a previously registered BroadcastReceiver. |
主要類
BroadcastReceiver
Base class for code that will receive intents sent by sendBroadcast().
翻譯:基礎(chǔ)類可以接受來自sendBroadcast()發(fā)出的intents饼问。
如果你不需要在應(yīng)用程序發(fā)送廣播,考慮使用localbroadcastmanager類代替接下來描述的一般工具揭斧。這會給你一個更有效的實現(xiàn)(無需跨進(jìn)程通信)莱革,并允許您避免考慮與其他應(yīng)用程序能夠接收或發(fā)送廣播任何安全問題峻堰。
您可以動態(tài)地注冊這個類用Context.registerReceiver()方法或靜態(tài)的實例,通過發(fā)布在AndroidManifest.xml中的<接收>標(biāo)記的實現(xiàn)盅视。
注意:如果注冊一個接收器在Activity.onResume()函數(shù)捐名,你需要反注冊在Activity.onPause(). 這將減少不必要的系統(tǒng)開銷。不要在Activity.onSaveInstanceState()注冊闹击。
有兩個主要的類的廣播可以用來接收镶蹋。
- 普通廣播:(使用 Context.sendBroadcast發(fā)出)是完全異步的。所有接收者都運行在一個未定義的順序里赏半,有時甚至同時接收贺归。這很高效,但也意味著不能使用結(jié)束或暫停API断箫。
- 有序廣播:(使用 Context.sendOrderedBroadcast發(fā)出)同一時間只傳遞一個接收器拂酣。每個接收器依次執(zhí)行,它可以傳送結(jié)果到下一個接收器仲义,當(dāng)然也可以暫停傳送婶熬。這個順序在android:priority屬性里通過 intent-filter定義,如果定義同樣的優(yōu)先級則是隨機(jī)順序埃撵。
安全性
有這么幾點建議:
- 這個Intent的命名空間是全局的赵颅。
- 當(dāng)你使用registerReceiver(),任何應(yīng)用程序可以向該注冊的接收者發(fā)送廣播暂刘。你可以控制誰可以通過定義的權(quán)限發(fā)送廣播到它饺谬。
- 當(dāng)你在應(yīng)用程序的清單中發(fā)布一個接收器并為它指定一個IntentFilter,任何其他應(yīng)用程序都可以發(fā)送到它的廣播鸳惯,不管你指定的篩選器商蕴。為了防止別人發(fā)送到它,使他們無法使用安卓:android:exported="false"芝发。
- 當(dāng)你使用sendBroadcast(Intent)或者相關(guān)方法绪商,一般任何其他應(yīng)用程序都可以接收這些廣播。你可以通過定義的權(quán)限控制誰可以接收這些廣播辅鲸。另外格郁,從ice_cream_sandwich,你也可以安全限制廣播到單個應(yīng)用程序利用Intent.setpackage独悴。
接收者的生命周期
一個廣播接收者有一個回調(diào)方法:void onReceive()例书。當(dāng)一個廣播消息到達(dá)接收者時,Android調(diào)用它的onReceive()方法并傳遞給它包含消息的Intent對象刻炒。廣播接收者被認(rèn)為僅當(dāng)它執(zhí)行這個方法時是活躍的决采。當(dāng)onReceive()返回后,它是不活躍的坟奥。有一個活躍的廣播接收者的進(jìn)程是受保護(hù)的树瞭,不會被殺死拇厢。但是系統(tǒng)可以在任何時候殺死僅有不活躍組件的進(jìn)程,當(dāng)占用的內(nèi)存別的進(jìn)程需要時晒喷。
特別是孝偎,你可能不會顯示一個對話框或綁定到一個服務(wù)在一個BroadcastReceiver中。對于前者凉敲,你應(yīng)該使用NotificationManager API衣盾。對于后者,你可以使用上下文:startservice()將命令發(fā)送到服務(wù)爷抓。
進(jìn)程的生命周期
一個進(jìn)程势决,目前正在執(zhí)行一個BroadcastReceiver(即目前在運行onReceive代碼(Context,Intent)函數(shù))被認(rèn)為是一個前臺進(jìn)程將保持運行的系統(tǒng)除了在極端的內(nèi)存壓力下。
這意味著如果想保持進(jìn)程長時間運行可以經(jīng)常利用一個服務(wù)去調(diào)用BroadcastReceiver來保持進(jìn)程不被刪除
onReceive()
這個方法是當(dāng)BroadcastReceiver收到一個Intent broadcast消息是被調(diào)用废赞。該方法是在其進(jìn)程的主線程調(diào)用的徽龟,除非明確地要求運行在不同的線程利用registerReceiver(BroadcastReceiver, IntentFilter, String, android.os.Handler)這個函數(shù)。不允許在主線程做耗時的任務(wù)唉地,因此也不要onreceive()推出彈出對話框据悔。
如果這個BroadcastReceiver通過<receiver>標(biāo)簽發(fā)送,當(dāng)這個函數(shù)返回后這個對象將不在存在耘沼。這意味著你不應(yīng)該進(jìn)行任何操作在返回結(jié)果后特別是異步极颓,對正在互動的服務(wù),應(yīng)該用startService(Intent)代替bindService(Intent, ServiceConnection, int)群嗤。如果你希望和正在運行的服務(wù)互動菠隆,應(yīng)該調(diào)用peekService(Context, Intent)。
被用在registerReceiver(BroadcastReceiver, IntentFilter) 和application manifests的IntentFilter不保證獨有狂秘。onReceive()實現(xiàn)應(yīng)該只對已知的action作出反應(yīng)骇径,忽略那些未知的被收到的Intent。