Android學習之基礎知識八—Android廣播機制


一、廣播機制簡介

  Android提供了一套完整的API,允許應用程序自由的發送和接受廣播,發送廣播借助於我們之前學過的:Intent,而接收廣播需要借助於廣播接收器(Broadcast Receiver)

  廣播的類型主要分為兩種:標准廣播和有序廣播。

  標准廣播:一種完全異步執行的廣播,在廣播發出之后,所有接收器幾乎在同一時刻接收到這條廣播消息,因此它們之間沒有任何的先后順序可言,這種廣播的效率會比較高,但是同時也意味着它無法被截斷的。標准廣播的工作流程圖如圖所示:

  有序廣播:一種同步執行的廣播,在廣播發出之后,同一時刻只會有一個廣播接收器能夠接收到這條廣播,當這個廣播接收器中的邏輯執行完畢后,廣播才會繼續傳遞,所以這種廣播接收器是有先后順序的,優先級高的廣播接收器就可以先收到廣播消息,並且前面的廣播接收器還可以截斷正在傳遞的廣播,這樣后面的廣播接收器就無法收到廣播消息了。有序廣播的工作流程如圖所示:

二、接收系統廣播

  Android內置了很多的系統級別的廣播,我們可以在應用程序中提通過監聽這些廣播來得到各種系統的狀態信息。比如手機開機、電池的電量、時間或時區發生改變等情況下發出一條廣播,要接受這些廣播,就需要使用廣播接收器。

  廣播接收器可以自由的對自己感興趣的廣播進行注冊,注冊廣播的方式一般有兩種,在代碼中注冊稱為動態注冊,在AndroidManifest.xml中注冊稱為靜態注冊。

2.1  動態注冊監聽網絡變化

第一步:聲明網絡權限。Android系統為了保護用戶設備的安全和隱私,做了嚴格的規定:如果程序需要進行一些對用戶來說比較敏感的操縱,就必須在配置文件中聲明權限才可以,否則程序將會直接崩潰。這里訪問的是系統的網絡狀態,所以需要進行以下權限聲明。

 

第二步:

 在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.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

 

四、 使用本地廣播

  前面我們發送和接收的廣播都是屬於系統全局廣播,即發出的廣播可以被其他應用程序接收到,並且我們也可以接收來自於其他應用程序的廣播。這樣就很容易引起安全性問題,比如說

我們發送的一些攜帶關鍵性數據的廣播有可能被其他應用程序截獲,或者其他應用程序不停的向我們的廣播接收器發送各種垃圾廣播。

  為了解決廣播的安全性問題,Android提供了一套本地的廣播機制,使用這個機制發出的廣播只能在應用程序的內部傳遞,並且廣播接收器也只能接收來自本應用程序發出的廣播,這樣所有的安全性問題就不存在了。

 第一步:修改MainActivity活動中的代碼:

第二步:運行程序,點擊按鈕,就會彈出:received local Broadcast  的提示信息。如果我們在BroadcastTest2這個應用程序中也去接收這條廣播,很明顯是接收不到的,因為這條廣播只在BroadcastTest程序中傳播。

 

本地廣播的注意事項:

  本地廣播是無法通過靜態注冊的方式來接收的,因為靜態注冊主要是為了讓程序在未啟動的情況下也能接收到廣播,而發送本地廣播時,我們的程序肯定是已經啟動了,因此完全不需要使用靜態注冊的功能。

本地廣播的幾點優勢:

  1、可以明確地知道正在發送的廣播不會離開我們的應用程序,因此不必擔心機密數據泄漏

  2、其他程序無法將廣播發送到我們程序的內部,因此不需要擔心會有安全漏洞的隱患

  3、發送本地廣播比發送系統全局廣播將會更加高效


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM