1、廣播機制簡介android
Android提供了一套完整的API,容許應用程序自由的發送和接受廣播,發送廣播藉助於咱們以前學過的:Intent,而接收廣播須要藉助於廣播接收器(Broadcast Receiver)安全
廣播的類型主要分爲兩種:標準廣播和有序廣播。網絡
標準廣播:一種徹底異步執行的廣播,在廣播發出以後,全部接收器幾乎在同一時刻接收到這條廣播消息,所以它們之間沒有任何的前後順序可言,這種廣播的效率會比較高,可是同時也意味着它沒法被截斷的。標準廣播的工做流程圖如圖所示:異步
有序廣播:一種同步執行的廣播,在廣播發出以後,同一時刻只會有一個廣播接收器可以接收到這條廣播,當這個廣播接收器中的邏輯執行完畢後,廣播纔會繼續傳遞,因此這種廣播接收器是有前後順序的,優先級高的廣播接收器就能夠先收到廣播消息,而且前面的廣播接收器還能夠截斷正在傳遞的廣播,這樣後面的廣播接收器就沒法收到廣播消息了。有序廣播的工做流程如圖所示:spa
2、接收系統廣播3d
Android內置了不少的系統級別的廣播,咱們能夠在應用程序中提經過監聽這些廣播來獲得各類系統的狀態信息。好比手機開機、電池的電量、時間或時區發生改變等狀況下發出一條廣播,要接受這些廣播,就須要使用廣播接收器。code
廣播接收器能夠自由的對本身感興趣的廣播進行註冊,註冊廣播的方式通常有兩種,在代碼中註冊稱爲動態註冊,在AndroidManifest.xml中註冊稱爲靜態註冊。xml
2.1 動態註冊監聽網絡變化對象
第一步:聲明網絡權限。Android系統爲了保護用戶設備的安全和隱私,作了嚴格的規定:若是程序須要進行一些對用戶來講比較敏感的操縱,就必須在配置文件中聲明權限才能夠,不然程序將會直接崩潰。這裏訪問的是系統的網絡狀態,因此須要進行如下權限聲明。blog
第二步:
在MainActivity活動中建立廣播接收器,並進行註冊
第三步:運行程序,會彈出:network is available的提示(左),接着點擊Home鍵,不要點擊Back鍵,回到主界面後,進入設置,打開手機的飛行模式,會彈出:network is unavailable(右)
2.2 靜態註冊廣播接收器
動態註冊的廣播接收器能夠自由的控制註冊與註銷,在靈活性方面有很大的優點,可是它有一個缺點,就是必需要在程序啓動以後才能接收到廣播,由於註冊的邏輯是寫在onCreate()方法中的。爲了讓程序在未啓動的狀況下就能收到廣播,就須要使用到靜態註冊方式了。
第一步:先建立一個廣播接收器BroadCompleteReceiver,New--->Other--->Broadcast Receiver.
Exported:表示是否容許這個廣播接收器接收本程序之外的廣播
Enabled:表示是否啓用這個廣播接收器。
第二步:在建立的廣播接收器中設置一個Toast顯示,表示當這個廣播接收器接收到消息後彈出一個提示信息。
第三步:在AndroidManifest.xml中對建立的廣播接收器添加想要監聽的action,並進行權限聲明,注意:咱們在建立BroadCompleteReceiver廣播接收器的時候,系統就已經自動在AndroidManifest.xml中註冊了。
Android系統啓動完成後會發出一條值爲:android.intent.action.BOOT_COMPLETED 的廣播,所以咱們在<Intent-filter>標籤中添加相應的action。而後使用<user-permission>標籤中又添加一條:android.permission.RECEIVE_BOOT_COMPLETED權限。
第四步:關閉模擬器再打開,就會收到一個開機廣播
3、發送自定義廣播
前面咱們提到廣播有兩種類型:標準廣播和有序廣播
3.1 發送標準廣播
第一步:建立一個自定義廣播接收器,用於接收到廣播後執行的操做
第二步:在AndroidManifest.xml中註冊:MyReceiver廣播接收器(已自動註冊),給發送的廣播自定義一個值:
<action android:name="com.workspace.hh.broadcasttest.MY_RECEIVER"/>
第三步:在activity_main.xml中設置一個按鈕,經過點擊按鈕來發送自定義的廣播
第四步:在MainActivity的:onCreate()方法中爲按鈕設置監聽事件:
發送廣播時,先建立一個Intent對象,把須要發送的廣播的值傳入,而後調用:context的sendBroadcast()方法,把廣播發送出去。這樣全部監聽:com.workspace.hh.broadcasttest.MY_RECEICER 這條廣播的廣播接收器就會收到消息。
第五步:運行程序,點擊按鈕發送廣播
3.2 廣播跨進程通訊
廣播時一種能夠跨進程的通訊方式,所以咱們在應用程序內發出的廣播,在其餘應用程序也能收到,下面咱們就來看一下效果:
第一步:新建一個項目:BroadcastTest2,並自定義一個廣播接收器:AnotherBroadcastReceiver,而後在AndroidManifest.xml中添加要監聽的廣播的值:com.workspace.hh.broadcasttest.MY_RECEIVER
第二步:運行項目BroadcastTest2,而後在BroadcastTest項目程序中點擊按鈕,能夠看到前後彈出來兩個提示信息,這說明兩個應用程序都接收到了廣播
3.3 發送有序廣播
發送有序只須要修改一個地方就好了:將:sendBroadcast()改成:sendOrderedBroadcast().
sendOrderedBroadcast()方法接收兩個參數:一個是Intent,另外一個是與權限相關的字符串,這裏傳入null就好了。
修改這個地方事後,雖然發送的廣播已是有序廣播了,可是效果仍是與標準廣播同樣會彈出兩個提示信息,下面咱們來經過截斷廣播看效果:
第一步:給:MyReceiver廣播接收器設置優先級,使得:MyReceiver比其餘廣播接收器先接收到廣播,在AndroidManifest.xml中經過:android:priority 屬性給廣播接收器設置優先級
第二步:在MyReceiver廣播接收器中截斷廣播,及後面的接收器就接收不到廣播了,在Toast提示信息下面添加:abortBroadcast()方法,該方法表示在此截斷廣播,後面的廣播接收器就再也接收不到該廣播了。
第四步:從新運行BroadcastTest和BroadcastTest2這兩個程序,而後點擊BroadcastTest程序中的按鈕,咱們看到只有一條提示信息彈出來:received in myReceiver
4、 使用本地廣播
前面咱們發送和接收的廣播都是屬於系統全局廣播,即發出的廣播能夠被其餘應用程序接收到,而且咱們也能夠接收來自於其餘應用程序的廣播。這樣就很容易引發安全性問題,好比說
咱們發送的一些攜帶關鍵性數據的廣播有可能被其餘應用程序截獲,或者其餘應用程序不停的向咱們的廣播接收器發送各類垃圾廣播。
爲了解決廣播的安全性問題,Android提供了一套本地的廣播機制,使用這個機制發出的廣播只能在應用程序的內部傳遞,而且廣播接收器也只能接收來自本應用程序發出的廣播,這樣全部的安全性問題就不存在了。
第一步:修改MainActivity活動中的代碼:
第二步:運行程序,點擊按鈕,就會彈出:received local Broadcast 的提示信息。若是咱們在BroadcastTest2這個應用程序中也去接收這條廣播,很明顯是接收不到的,由於這條廣播只在BroadcastTest程序中傳播。
本地廣播的注意事項:
本地廣播是沒法經過靜態註冊的方式來接收的,由於靜態註冊主要是爲了讓程序在未啓動的狀況下也能接收到廣播,而發送本地廣播時,咱們的程序確定是已經啓動了,所以徹底不須要使用靜態註冊的功能。
本地廣播的幾點優點:
一、能夠明確地知道正在發送的廣播不會離開咱們的應用程序,所以沒必要擔憂機密數據泄漏
二、其餘程序沒法將廣播發送到咱們程序的內部,所以不須要擔憂會有安全漏洞的隱患
三、發送本地廣播比發送系統全局廣播將會更加高效