1. 程式人生 > >Android學習之基礎知識八—Android廣播機制

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

iss 所有 系統 運行 perm 情況 space dcom image

一、廣播機制簡介

  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、發送本地廣播比發送系統全局廣播將會更加高效

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