BroadcastReceiver 詳細解析

廣播是一種廣泛運用的在應(yīng)用程序之間傳輸信息的機制浙滤,主要用來監(jiān)聽系統(tǒng)或者應(yīng)用發(fā)出的廣播信息泼差,然后根據(jù)廣播信息作為相應(yīng)的邏輯處理,也可以用來傳輸少量组砚、頻率低的數(shù)據(jù)。

在實現(xiàn)開機啟動服務(wù)和網(wǎng)絡(luò)狀態(tài)改變掏颊、電量變化糟红、短信和來電時通過接收系統(tǒng)的廣播讓應(yīng)用程序作出相應(yīng)的處理艾帐。

BroadcastReceiver 自身并不實現(xiàn)圖形用戶界面,但是當它收到某個通知后盆偿, BroadcastReceiver 可以通過啟動 Service 柒爸、啟動 Activity 或是 NotificationMananger 提醒用戶。

使用廣播的注意事項

當系統(tǒng)或應(yīng)用發(fā)出廣播時陈肛,將會掃描系統(tǒng)中的所有廣播接收者揍鸟,通過 action 匹配將廣播發(fā)送給相應(yīng)的接收者,接收者收到廣播后將會產(chǎn)生一個廣播接收者的實例句旱,執(zhí)行其中的 onReceiver() 這個方法阳藻;特別需要注意的是這個實例的生命周期只有10秒,如果10秒內(nèi)沒執(zhí)行結(jié)束 onReceiver() 谈撒,系統(tǒng)將會報錯腥泥。在 onReceiver() 執(zhí)行完畢之后,該實例將會被銷毀啃匿,所以不要在 onReceiver() 中執(zhí)行耗時操作蛔外,也不要在里面創(chuàng)建子線程處理業(yè)務(wù)(因為可能子線程沒處理完,接收者就被回收了溯乒,那么子線程也會跟著被回收掉)夹厌;正確的處理方法就是通過 intent 調(diào)用 Activity 或者 Service 處理業(yè)務(wù)。

BroadcastReceiver的注冊

BroadcastReceiver 的注冊方式有且只有兩種裆悄,一種是靜態(tài)注冊(推薦使用)矛纹,另外一種是動態(tài)注冊,廣播接收者在注冊后就開始監(jiān)聽系統(tǒng)或者應(yīng)用之間發(fā)送的廣播消息光稼。

下面通過例子看一下兩種注冊方式,先定義一個接收短信的 BroadcastReceiver 類:

public class MyBroadcastReceiver extends BroadcastReceiver {
    // action 名稱
    String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED" ;
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals( SMS_RECEIVED )) {
            // 一個receiver可以接收多個action的艾君,即可以有
            // 多個intent-filter,需要在 onReceive
            // 里面對 intent.getAction(action name) 進行判斷蹬癌。
            ...
        }
    }
}
  • 靜態(tài)注冊

    在 AndroidManifest.xml 的 application 里面定義 receiver 并設(shè)置要接收的action。

    < receiver android:name = ".MyBroadcastReceiver" > 
        < intent-filter android:priority = "777" >       
            <action android:name = "android.provider.Telephony.SMS_RECEIVED" />
        </ intent-filter > 
    </ receiver >
    

    這里的 priority 取值是 -1000 到 1000 虹茶,值越大優(yōu)先級越高冀瓦,同時注意加上系統(tǒng)接收短信的限權(quán)写烤。

    靜態(tài)注冊的廣播接收者是一個常駐在系統(tǒng)中的全局監(jiān)聽器翼闽,當你在應(yīng)用中配置了一個靜態(tài)的 BroadcastReceiver 洲炊,安裝了應(yīng)用后而無論應(yīng)用是否處于運行狀態(tài)感局,廣播接收者都是已經(jīng)常駐在系統(tǒng)中了尼啡。同時應(yīng)用里的所有 receiver 都在清單文件里面,方便查看询微。要銷毀掉靜態(tài)注冊的廣播接收者,可以通過調(diào)用 PackageManager 將 Receiver 禁用撑毛。

  • 動態(tài)注冊

    在 Activity 中聲明 BroadcastReceiver 的擴展對象,在 onResume 中注冊雌续,onPause 中卸載.

    public class MainActivity extends Activity {
        MyBroadcastReceiver receiver;
    
        @Override
        protected void onResume() {
            // 動態(tài)注冊廣播 (代碼執(zhí)行到這才會開始監(jiān)聽廣播消息胯杭,并對廣播消息作為相應(yīng)的處理)
            receiver = new MyBroadcastReceiver();
            IntentFilter intentFilter = new IntentFilter( "android.provider.Telephony.SMS_RECEIVED" );
            registerReceiver( receiver , intentFilter); 
            super.onResume();
        }
    
        @Override
        protected void onPause() { 
            // 撤銷注冊 (撤銷注冊后廣播接收者將不會再監(jiān)聽系統(tǒng)的廣播消息)
            unregisterReceiver(receiver);
            super.onPause();
        }
    }
    
  • 靜態(tài)注冊和動態(tài)注冊的區(qū)別

    1. 靜態(tài)注冊的廣播接收者一經(jīng)安裝就常駐在系統(tǒng)之中,不需要重新啟動喚醒接收者做个;動態(tài)注冊的廣播接收者隨著應(yīng)用的生命周期,由 registerReceiver 開始監(jiān)聽顽频,由 unregisterReceiver 撤銷監(jiān)聽太闺,如果應(yīng)用退出后,沒有撤銷已經(jīng)注冊的接收者應(yīng)用應(yīng)用將會報錯跟束。

    2. 當廣播接收者通過 intent 啟動一個 activity 或者 service 時丑孩,如果 intent 中無法匹配到相應(yīng)的組件。動態(tài)注冊的廣播接收者將會導(dǎo)致應(yīng)用報錯,而靜態(tài)注冊的廣播接收者將不會有任何報錯温学,因為自從應(yīng)用安裝完成后,廣播接收者跟應(yīng)用已經(jīng)脫離了關(guān)系逃延。

發(fā)送廣播主要類型

  • 普通廣播

    普通廣播是完全異步的轧拄,可以在同一時刻(邏輯上)被所有接收者接收到,所有滿足條件的 BroadcastReceiver 都會隨機地執(zhí)行其 onReceive() 方法檩电。

    同級別接收是先后是隨機的拄丰;級別低的收到廣播;消息傳遞的效率比較高料按,并且無法中斷廣播的傳播。

    Intent intent = new Intent("android.provider.Telephony.SMS_RECEIVED"); 
    //通過intent傳遞少量數(shù)據(jù)
    intent.putExtra("data", "finch"); 
    // 發(fā)送普通廣播
    sendBroadcast(Intent);
    
  • 有序廣播

    有序廣播通過 Context.sendOrderedBroadcast() 來發(fā)送垄潮,所有的廣播接收器優(yōu)先級依次執(zhí)行闷盔,廣播接收器的優(yōu)先級通過 receiver 的 intent-filter 中的 android:priority 屬性來設(shè)置,數(shù)值越大優(yōu)先級越高馁筐。

    當廣播接收器接收到廣播后,可以使用 setResult() 函數(shù)來結(jié)果傳給下一個廣播接收器接收果正,然后通過 getResult() 函數(shù)來取得上個廣播接收器接收返回的結(jié)果盟迟。

    當廣播接收器接收到廣播后,也可以用 abortBroadcast() 函數(shù)來讓系統(tǒng)攔截下來該廣播攒菠,并將該廣播丟棄,使該廣播不再傳送到別的廣播接收器接收卓起。

  • 本地廣播

    在 API21 的 Support v4 包中新增本地廣播凹炸,也就是 LocalBroadcastManager 。由于之前的廣播都是全局的奕筐,所有應(yīng)用程序都可以接收到,這樣就會帶來安全隱患墓阀,所以我們使用 LocalBroadcastManager 只發(fā)送給自己應(yīng)用內(nèi)的信息廣播渊胸,限制在進程內(nèi)使用蹬刷。

    它的用法很簡單,只需要把調(diào)用 context 的 sendBroadcast泡态、registerReceiver迂卢、unregisterReceiver 的地方換為 LocalBroadcastManager.getInstance(Context context)中對應(yīng)的函數(shù)即可。

    這里創(chuàng)建廣播的過程和普通廣播是一樣的過程而克,這里就不過多介紹了

  • 系統(tǒng)廣播

    當然系統(tǒng)中也會有很多自帶的廣播,當符合一定條件時腾降,系統(tǒng)會發(fā)送一些定義好的廣播碎绎,比如:重啟、充電筋帖、來電電話等等。我們可以通過action屬性來監(jiān)聽我們的系統(tǒng)廣播,創(chuàng)建廣播的過程和普通廣播是一樣的過程寄啼,這里就不過多介紹了代箭。

    常用的廣播action屬性有:

    • 屏幕被關(guān)閉之后的廣播:Intent.ACTION_SCREEN_OFF

    • 屏幕被打開之后的廣播:Intent.ACTION_SCREEN_ON

    • 充電狀態(tài),或者電池的電量發(fā)生變化:Intent.ACTION_BATTERY_CHANGED

    • 關(guān)閉或打開飛行模式時的廣播:Intent.ACTION_AIRPLANE_MODE_CHANGED

    • 表示電池電量低:Intent.ACTION_BATTERY_LOW

    • 表示電池電量充足乙帮,即電池電量飽滿時會發(fā)出廣播:Intent.ACTION_BATTERY_OKAY

    • 按下照相時的拍照按鍵(硬件按鍵)時發(fā)出的廣播:Intent.ACTION_CAMERA_BUTTON

    值得注意的是蛤高,隨著系統(tǒng)版本的提升碑幅,很多系統(tǒng)廣播已經(jīng)不再被支持,如果你需要使用哪個系統(tǒng)廣播沟涨,最好看看最新版本的支持情況。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末喜庞,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子延都,更是在濱河造成了極大的恐慌,老刑警劉巖求摇,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件殊者,死亡現(xiàn)場離奇詭異,居然都是意外死亡摔刁,警方通過查閱死者的電腦和手機海蔽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來趁俊,“玉大人刑然,你說我怎么就攤上這事∑寐樱” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵挡逼,是天一觀的道長腻豌。 經(jīng)常有香客問我,道長吝梅,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任做瞪,我火速辦了婚禮,結(jié)果婚禮上著拭,老公的妹妹穿的比我還像新娘牍帚。我一直安慰自己,他們只是感情好履羞,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布忆首。 她就那樣靜靜地躺著爱榔,像睡著了一般糙及。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上唇聘,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天柱搜,我揣著相機與錄音,去河邊找鬼聪蘸。 笑死,一個胖子當著我的面吹牛控乾,可吹牛的內(nèi)容都是我干的娜遵。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼慨仿,長吁一口氣:“原來是場噩夢啊……” “哼纳胧!你這毒婦竟也來了镰吆?” 一聲冷哼從身側(cè)響起躲雅,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤相赁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后钮科,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡佳励,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年蛆挫,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瞧剖。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡可免,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出浇借,到底是詐尸還是另有隱情,我是刑警寧澤巾遭,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布修己,位于F島的核電站,受9級特大地震影響片仿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜砂豌,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一光督、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧结借,春花似錦、人聲如沸咖熟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽确沸。三九已至捌锭,卻和暖如春罗捎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背桨菜。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工雷激, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人屎暇。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像凶异,于是被迫代替她去往敵國和親挤巡。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 本文轉(zhuǎn)載自http://www.cnblogs.com/lwbqqyumidi/p/4168017.html 1....
    Ernest_Chang閱讀 707評論 0 3
  • 前言 本來想寫一下廣播的喉恋,發(fā)現(xiàn)查閱后有整理的不錯的母廷,只好轉(zhuǎn)載圖個簡便,日后好復(fù)習(xí)轉(zhuǎn)載:http://www.cnb...
    提升即效率閱讀 1,386評論 0 10
  • Broadcasts Android apps can send or receive broadcast mes...
    woitaylor閱讀 6,308評論 0 12
  • 廣播接收器 是Android的四大組件之一氓鄙,可見廣播在Android中的重要性业舍; 1. 什么是廣播升酣? 廣播(Bro...
    Lost_Robot閱讀 1,945評論 2 10
  • offsetHeight:元素本身的高度态罪,包括邊框 offsetTop:基于定位父類元素的偏移量(距離) scro...
    Amundsen閱讀 272評論 0 0