10.7 接收廣播消息

Android系統(tǒng)的四大組件還有一種BroadcastReceiver,這種組件本質(zhì)上就是一個全局監(jiān)聽器,用于監(jiān)聽全局的廣播消息。由于BroadcastReceiver是一個全局監(jiān)聽器,因此它可以非常方便地實(shí)現(xiàn)系統(tǒng)中不同組件之間的通訊。例如,我們希望客戶端程序與startService()方法啟動的Service之間通訊,就可以借助于BroadcastReceiver來實(shí)現(xiàn)。

10.7.1 BroadcastReceiver用于接收程序(包括用戶開發(fā)的程序和系統(tǒng)內(nèi)建的程序)所發(fā)出的Broadcast Intent,與應(yīng)用程序啟動Activity、Service相同的是,程序啟動BroadcastReceiver也只需要兩步。

1、創(chuàng)建需要啟動的BroadcastReceiver的Intent。

2、調(diào)用Content的sendBroadcast()或sendOrderdBroadcast()方法啟動指定的BroadcastReceiver。

與Activity、Service具有完整的生命周期不同,BroadcastReceiver本質(zhì)上只是一個系統(tǒng)級的監(jiān)聽器--------它專門負(fù)責(zé)監(jiān)聽個程序所發(fā)出的Broadcast。

提示:

前面介紹的各種OnXxxListener只是程序級別的監(jiān)聽器,這些監(jiān)聽器運(yùn)行在指定程序所在進(jìn)程中,當(dāng)程序退出時,onXxxListener監(jiān)聽器也就隨之關(guān)閉了。但BroadcastReceiver屬于系統(tǒng)級的監(jiān)聽器,他擁有自己的進(jìn)程,只要存在與之匹配的Intent被廣播出來,BroadcastReceiver就會被激發(fā)。

由于BroadcastReceiver本質(zhì)上屬于一個監(jiān)聽器,因此實(shí)現(xiàn)BroadcastReceiver的方法也十分簡單,只要重寫B(tài)roadcastReceiver的onReceive(Content content,Intent intent)方法即可。

一旦實(shí)現(xiàn)了BroadcastReceiver,接下來就應(yīng)該指定該BroadcastReceiver能匹配的Intent,此時有兩種方式。

1、使用代碼進(jìn)行指定,調(diào)用BroadcastReceiver的Content的registerReceiver(BroadcastReceiver receiver,IntentFilter filter)方法指定。例如如下代碼

2、在AndroidManifest.xml文件中配置。例如如下代碼:

每次系統(tǒng)Broadcast事件發(fā)生后,系統(tǒng)就會創(chuàng)建對應(yīng)的BroadcastReceiver實(shí)例,并自動觸發(fā)它的onReceive()方法,onReceive()方法執(zhí)行完后,BroadcastReceiver實(shí)例就會被銷毀。

提示:

與Activity組件不同的是,當(dāng)系統(tǒng)通過Intent啟動指定了Activity組件時,如果系統(tǒng)沒有找到合適的Activity組件,則會導(dǎo)致程序異常終止;單系統(tǒng)通過Intent激發(fā)BroadcastReceiver時,如果找不到合適的BroadcastReceiver組件,應(yīng)用不會有任何問題 。

如果BroadcastReceiver的onReceive()方法不能在10秒內(nèi)執(zhí)行完成,Android會認(rèn)為該程序無響應(yīng),所以不要在BroadcastReceiver的onReceive()方法里面執(zhí)行一些耗時操作;否則會彈出ANR(Application No Response)對話框。

如果確實(shí)需要根據(jù)Broadcast來完成意向比較耗時的操作,則可以考慮通過Intent啟動一個Service來完成該操作。不應(yīng)該考慮使用新線程去完成耗時操作,因?yàn)锽roadcastReceiver本省的生命周期很短,可能出現(xiàn)的情況是子線程還沒有結(jié)束,BroadcastReceiver就已經(jīng)退出了。

如果BroadcastReceiver所在的進(jìn)程結(jié)束了,雖然該進(jìn)程內(nèi)還有用戶啟動的新線程,但由于該進(jìn)程內(nèi)不包含任何活動組件,因此系統(tǒng)可能在內(nèi)存緊張時優(yōu)先結(jié)束該進(jìn)程。這樣就可能導(dǎo)致BroadcastReceiver啟動的子線程不能執(zhí)行完成。

10.7.2 ?發(fā)送廣播

在程序中發(fā)送廣播十分簡單,只要調(diào)用Content的sendBroadast(Intent intent)方法即可,這條廣播將會啟動intent參數(shù)所對應(yīng)的BroadcastReceiver。

下面簡單的程序示范了如何發(fā)送Broadcast、使用BroadcastReceiver接收廣播。該程序的Activity界面中包含一個按鈕,當(dāng)用戶單擊按鈕時程序會向外發(fā)送一條廣播,該程序的代碼如下。

上面的程序中創(chuàng)建了一個Intent對象,并使用該Intent對象對外發(fā)送一條廣播。個hi按行層序所使用的BroadcastReceiver代碼如下。

真能夠如上面的程序中看到的,當(dāng)符合該action的廣播出現(xiàn)時,該廣播的onReceive()方法將會被處罰,從而在該方法中顯示廣播攜帶的消息。

上面發(fā)送廣播的程序中指定發(fā)送廣播時所用的Intent的Action為org.cxrazyit.action.CRAZY_BROADCAST,這就需要配置上面的BroadcastReceiver應(yīng)監(jiān)聽Action為該字符串的Intent,在AndroidManifest.xml文件中增加如下配置即可:

可以運(yùn)行一下試試看

10.7.3 有序廣播

Broadcast被分為如下兩種。

1、Normal Broadcast(普通廣播):Normal Broadcast是完全異步的,可以在同一時刻(邏輯上)被所有的接收者接收到,消息傳遞的效率比較高。但缺點(diǎn)是接收者不能將處理結(jié)果傳遞給下一個接收者,并卻無法終止Broadcast Intent的傳播。

2、Ordered Broadcast(有序廣播):Ordered Broadcast的接收者將預(yù)先聲明的優(yōu)先級依次接收Broadcast。比如A的級別高于B、B的級別高于C,那么Broadcast先傳給A,再傳給B。最后傳給C。優(yōu)先級別聲明在<intent-filter.....>元素的android:priority屬性中,數(shù)越大級別越高,取值范圍-1000-1000,也可以調(diào)用IntentFilter對象的setPriority()設(shè)置優(yōu)先級別。Ordered Broadcast接收者可以終止Broadcast Intent的傳播。Broadcast Intent的出阿伯一旦終止,后面的接收者就無法接收到Broadcast。另外,Ordered Broadcast的接收者可以將數(shù)據(jù)傳遞給下一個結(jié)合搜著,比如A得到Broadcast后,可以往它的結(jié)果對象中存入數(shù)據(jù),當(dāng)Broadcast傳給B,B可以從A的結(jié)果對象得到A存入的數(shù)據(jù)。

Content提供兩個方法用于發(fā)送廣播。

sendBroadcast() :發(fā)送Normal Broadcast。

sendOrderedBroadcast():發(fā)送Ordered Broadcast

對于Ordered?Broadcast而言,系統(tǒng)會根據(jù)接收者聲明的優(yōu)先級別按順序諸葛執(zhí)行接收者,優(yōu)先接受到Broadcast的接收者可以終止Broadcast,調(diào)用BroadcastReceiver的abortBroadcast()

方法即刻終止Broadcast。如果Broadcast背前面的接收者終止,后面的廣播接收者就在也無法獲取到Broadcast了。

不僅如此,對于Ordered Broadcast而言,優(yōu)先接收到Broadcast的接收者可以通過serResultExtras(Bundle)方法將處理結(jié)果存入Broadcast中,然后傳給下一個接收者,下一個接收者通過代碼Bundle bundle = getResultExtras(true)可以獲取上一個接收者存入的數(shù)據(jù)。

提示:

系統(tǒng)接收到短信,發(fā)出Broadcast屬于Ordered ?Broadcast。如果想阻止用戶收到短信,可以通過設(shè)置優(yōu)先級,讓自定義的BroadcastReceiver現(xiàn)貨區(qū)到Broadcast,然后總之Broadcast。

接下來介紹一下發(fā)送廣播的示例,該程序的Activity界面上只有一個普通的按鈕,用于發(fā)送一條有序廣播。該程序代碼如下。



上面程序中的粗體字代碼指定了Intent的Action屬性,再調(diào)用endOrderedBroadcast()方法來發(fā)送有序廣播。對于有序廣播而言,他會按優(yōu)先級依次觸發(fā)每個BroadcastReceiver的onReceive()方法。

下面的程序定義了第一個BroadcastReceiver。

上面的BroadcastReceiver不僅處理了他所接受的消息,而且向處理結(jié)果中存入了Key為first的消息,這個消息將可以被第二個BroadcastReceiver解析出來。

上面的程序中的1號字體代碼用于取消廣播,如果保持這條代碼生效,那么優(yōu)先級比MyReceiver低的BroadcastReceiver都將不會被處罰。

在AndroidManifest.xml文件中部署該BroadcastReceiver,并制定其優(yōu)先級為20.配置片段如下:

接下來微程序提供第二個BroadcastReceiver,這個BroadcastReceiver將會解析前一個BroadcastReceiver所存入的Key為first的消息。該BroadcastReceiver的代碼如下。


上面程序的代碼用于解析前一個BroadcastReceiver存儲結(jié)果的Key為first的消息,在AndroidManifest.xml文件中配置該BroadcastReceiver,并指定其優(yōu)先級為0.配置片段消息如下:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容