Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android BroadcastReceiver(一)

Android BroadcastReceiver(一)

編輯:關於Android編程

Android BroadcastReceiver


介紹: broadcastReceiver是android的四大組件之一,大部分的廣播是系統發出來的。例如,屏幕關閉,電池電量不足等等。應用同樣可以創建廣播,例如:當下載完成的時候,要讓其他的應用知道這個情況,需要用到broadcastreceiver,receiver沒有界面,它可能會創建一個status bar notification通知用戶。broadcastreceiver 只是會做一些非常小的工作,例如,它可以出發一個service工作。

 


基類的代碼會收到sendBroadcast()發送過來的Intents.

如果不需要在應用之間發送廣播,可以考慮使用LocalBroadcastManager代替下面介紹的方式。這種方式會有更好的性能,並且不用考慮不同應用之間的安全問題,因為其他的應用有可能可以接收這個廣播。

可以用Context.registerReceiver()動態注冊receiver或者是在AndroidManifest.xml 文件裡通過<receiver>元素靜態注冊receiver。

注意:    如果在Activity.onResume() 裡面注冊一個receiver,那麼必須在Activity.onPause() 方法裡面注銷這個receiver。不要在Activity.onSaveInstanceState() 方法裡面注銷receiver,因為當用戶回到歷史堆棧中不會調用它。

這裡有兩種主要的廣播可以收到:

正常的 broadcasts ( Context.sendBroadcast發送的) 都是異步的. 所有的receiver都是沒有順序的,通常在同一時間。這種方式效率更好,這意味著receiver不能使用結果或者終止API。
有序的 broadcasts (Context.sendOrderedBroadcast 發送的) 是同時發送給一個receiver。因為每一個receiver按照順序執行,那麼就可以傳遞結果到下一個receiver,或者它可以完全終止廣播,已達到不傳遞給下一個receiver。有序的receiver運行的時與android:priority 有關系,這個屬性可以控制它執行順序;如果receiver擁有同樣的priority,那麼它們的執行順序是任意的。
即使在正常的廣播中,系統在有些情況下會把廣播同時發給一個receiver。在特殊條件下,可能需要創建一個進程來處理receiver,在某一時間點只有一個receiver會運行,為了避免超負荷工作是系統可能創建新的進程。在這種情況下,然而,這些receiver還是不能夠返回結果和終止他們的廣播。

需要注意,即使Intent類被用來發送和接收廣播,Intent 廣播與啟動activity的機制是完全不同的。BroadcastReceiver 不能處理startActivity()方法發送出來的Intent,沒有這種機制;同樣的,當廣播一個Intent,同樣不能找到或者啟動一個activity。這兩種操作在語義上是完全不同的:通過Intent啟動一個activity是一個前台操作,這是隨著用戶的操作而發生的改變;廣播一個Intent是一種後台操作,用戶是不能意識到的.

下面有三個主題的內容:

Security
Receiver Lifecycle
Process Lifecycle
Security
receiver通常是應用之間通信的一個工具,因此必須考慮其他的應用可能如何濫用它們。需要考慮的問題有:

Intent的命名空間是全局的。要保證定義的action名字和其他的字符串都是屬於自己的應用,要不然會無意識的與系統其他的沖突。

如果是用 registerReceiver(BroadcastReceiver, IntentFilter)注冊Receiver, 任何應用都有可能發送廣播到那個receiver。可以通過定義permissions控制誰能發送廣播給它。

在manifest裡面定義receiver,並且定義了intent-filters, 任何應用都可以忽略指定的過濾條件並發送廣播給它。為了防止其他的應用發送廣播給它,在在manifest裡面定義android:exported="false",這樣其他的應用就不能發送廣播到這個receiver了。

用sendBroadcast(Intent)   或者相關的方法,正常情況,其他的應用可以收到這個廣播。需要通過定義permission控制可以接受這個廣播的receiver。或者是,從 ICE_CREAM_SANDWICH 開始,可以同通過設置Intent.setPackage 來指定receiver。

用 LocalBroadcastManager 就不會有這個些問題,從廣播發出後,都不會出當前進程。

receiver和broadcast都可以設置訪問權限。

為了在發送的時候執行permission,必須提供一個非空的permission參數給 sendBroadcast(Intent, String) 或者 sendOrderedBroadcast(Intent, String, BroadcastReceiver, android.os.Handler, int, String, Bundle). 僅僅定義這個permission的receiver可以接收廣播( AndroidManifest.xml 裡面定義<uses-permission>)。

當收到執行權限時,在注冊receiver的時候需要提供一個非空的permission參數--要麼當調用registerReceiver(BroadcastReceiver, IntentFilter, String, android.os.Handler) 或者是在AndroidManifest.xml 文件裡面定義一個靜態的<receiver>. 只有授予了指定permission的廣播才能夠發送到receiver中。

Receiver Lifecycle
BroadcastReceiver 對象只有在調用onReceive(Context, Intent)方法是才有效. 一旦從這個方法裡面返回,系統會認為這個對象已經完成並且不在處於活動狀態。

這裡是當實現 onReceive(Context, Intent) 時需要注意: 任何需要異步的操作是不可行的,因為需要從方法裡面返回,但是方法又要處理異步的操作,這樣就可以行了,這種情況下,系統會在異步操作完成之前可能會殺死BroadcastReceiver的進程。

特殊情況下,在BroadcastReceiver裡面可能不會顯示一個dialog或者綁定一個service。對於前者,用NotificationManager API代替,對後者,可以用 Context.startService() 發送命令給service。

Process Lifecycle
當前正在運行的BroadcastReceiver(運行在onReceive(Context, Intent)方法上)進程需要被認為是前台進程,並且會一直運行除非是系統的內存處於極限情況下(系統會回收內存)。

一旦從onReceive()返回,BroadcastReceiver不再是活動狀態的,它運行的進程與其他運行的在它裡面的應用組件一樣重要,這是非常特殊並且非常重要的,因為那個進程只是為BroadcastReceiver服務,然後receiver從onReceive()裡面返回,系統會認為這個進程是空的並且會盡快殺死它回收資源。

這就意味著,如果是一個長時間運行的操作,最好是用service和BroadcastReceiver 結合使用,為了保持進程在整個操作中持久運行。

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved