Andorid應用開發之BroadcastReceiver

BroadcastReceiver概述:

BroadcastReceiver是接收從sendBroadcast()發出的intent的基類。你可以通過Context.registerReceiver()方法在代碼中動態的註冊一個BroadcastReceiver的實例,也可以通過再AndroidManifest.xml文件中用<receiver>標籤來靜態聲明。

注意:如果你實在Activity.onResume()方法中註冊的一個receiver,那麼你必須在Activity.onPause()方法中進行註銷。(當一個activity處於暫停狀態是不會接收intents的,並且這樣做也可以減小系統不必要的開銷)。不要在Activity.onSaveInstanceState()方法中註銷receiver,因爲activity從棧中恢復的時候並不會調用這個方法了。

訂閱廣播:

<receiver android:name="MySMSListener">
   <intent-filter>
       <action 
android:name="android.provider.Telephony.SMS_RECEIVED"/>
   </intent-filter>
</receiver>
IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
IncomingSMSReceiver receiver = new IncomingSMSReceiver();
registerReceiver(receiver, filter);

可以接收的broadcast主要分爲兩種類型:
   普通的broadcasts(通過Context.sendBroadcast發送)是完全異步的。這個broadcast的receiver以無序的狀態運行,經常是在同一時刻運行。這種做法是十分高效的,但是也意味着receiver不能夠利用相互處理的結果或者是調用退出的API來退出(因爲不知道哪個receiver先接收到intent)。
   有序的broadcasts(通過Context.sendOrderedBroadcast發送)一次只發送給一個receiver。每一個receiver是有序的處理這個intent的,前面的receiver可以傳遞結果給下一個receiver,或者任意一個receiver都可以完全的退出,這樣intent就不會傳遞給其他的receivers.receiver的執行順序可以通過匹配的intent-filter中的android:priority屬性來控制;如果有多個receivers處於同一個優先級,那麼這幾個receivers將會以任意的順序來執行。
   即使是在廣播普通的broadcasts的情況下,系統也有可能在某些情況下轉換爲一次發送一個broadcast給一個receriver。特別是當receivers需要創建進程時,在同一時刻僅僅一個receiver可以運行,避免系統因爲這些新建的進程而過載。
   注意:儘管Intent類是用來發送和接受這些broadcasts,這裏的Intentbroadcast機制和那些通過Context.startActivity()方法來啓動activity的intent是完全獨立的。一個BroadcastReceiver是沒辦法觀察和捕獲一個用於啓動activity的intent的;同樣的,當你通過intent來發出broadcast時,你也不可能(通過這個intent)找到或者啓動一個activity的。這兩種操作是完全不同的:通過一個intent來啓動一個activity是一個前臺操作,會改變用戶當前交互的對象;而通過intent來發出broadcast是一個後臺操作,用戶經常是察覺不到的。
   BroadcastReceiver類(通過一個manifest的<receiver>標籤作爲一個組件啓動)是應用程序全局聲明週期重要的一部分。
  
討論的主題
   1、Receiver的生命週期
   2、權限
   3、進程的生命週期
  
可以接收的broadcast主要分爲兩種類型
       普通的broadcasts(通過Context.sendBroadcast發送)是完全異步的。這個broadcast的receiver以無序的狀態運行,經常是在同一時刻運行。這種做法是十分高效的,但是也意味着receiver不能夠利用相互處理的結果或者是調用退出的API來退出(因爲不知道哪個receiver先接收到intent)。

       有序的broadcasts(通過Context.sendOrderedBroadcast發送)一次只發送給一個receiver。每一個receiver是有序的處理這個intent的,前面的receiver可以傳遞結果給下一個receiver,或者任意一個receiver都可以完全的退出,這樣intent就不會傳遞給其他的receivers.receiver的執行順序可以通過匹配的intent-filter中的android:priority屬性來控制;如果有多個receivers處於同一個優先級,那麼這幾個receivers將會以任意的順序來執行。

       即使是在廣播普通的broadcasts的情況下,系統也有可能在某些情況下轉換爲一次發送一個broadcast給一個receriver。特別是當receivers需要創建進程時,在同一時刻僅僅一個receiver可以運行,避免系統因爲這些新建的進程而過載。

 

注意:

儘管Intent類是用來發送和接受這些broadcasts,這裏的Intentbroadcast機制和那些通過Context.startActivity()方法來啓動activity的intent是完全獨立的。一個BroadcastReceiver是沒辦法觀察和捕獲一個用於啓動activity的intent的;同樣的,當你通過intent來發出broadcast時,你也不可能(通過這個intent)找到或者啓動一個activity的。這兩種操作是完全不同的:通過一個intent來啓動一個activity是一個前臺操作,會改變用戶當前交互的對象;而通過intent來發出broadcast是一個後臺操作,用戶經常是察覺不到的。

BroadcastReceiver類(通過一個manifest的<receiver>標籤作爲一個組件啓動)是應用程序全局聲明週期重要的一部分。
  
討論的主題
   1、Receiver的生命週期
   2、權限
   3、進程的生命週期

Receiver的生命週期

一個BroadcastReceiver的對象僅僅在調用onReceiver(COntext,Intent)的時間中有效。一旦你的代碼從這個函數中返回,那麼系統就認爲這個對象應該結束了,不能再被激活。你在onReceive(Context, Intent)中的實現有着非常重要的影響:任何對於異步操作的請求都是不允許的,因爲你可能需要從這個函數中返回去處理異步的操作,但是在那種情況下,BroadcastReceiver將不會再被激活,因此係統就會再異步操作之前殺死這個進程。

特別是,你不應該再一個BroadcastReceiver中顯示一個對話框或者綁定一個服務。對於前者(顯示一個對話框),你應該用NotificationManagerAPI來替代,對於後者(綁定一個服務),你可以使用Context.startService()發送一個命令給那個服務來實現綁定效果。

 

權限

存取的權限可以通過在發送方的Intent或者接收方的Intent中強制指定。

       在發送一個broadcast時強制指定權限,就必須提供一個非空的peemission參數給sendBroadcast(Intent,String)或者是sendOrderedBroadcast(Intent, String,BroadcastReceiver, android.os.Handel, int, String, Bundle)。只有那些擁有這些權限(通過在ANdroidManifest.xml文件中相應的聲明<uses-permission>標籤)的receiver能夠接收這些broadcast。

在接收一個broadcast時強制指定權限,就必須在註冊receiver時提供一個非空的permission參數--無論是在調用registerReceiver(BroadcastReceiver, IntentFilter,String, android.os.Handler)或者是通過再AndroidManifest.xml文件中通過<receiver>靜態標籤來聲明。只有那些擁有這些權限(通過在相應的AndroidManifest.xml文件中查詢<uses-permission>標籤來獲知)的發送方將能夠給這個receiver發送Intent。

對於安全和權限的詳細內容請查看Security and Permission文檔。

 

進程的生命週期

一個正在執行BroadcastReceiver(也就是,正在執行onReceive(COntext, Intent)方法)的進程被認爲是一個前臺的進程,將會一直運行,除非系統處於內存極度低的情況下。

一旦從OnReceive()方法中返回,這個BroadcastReceiver將不會再被激活,此時它的主進程就和任何其他運行於此應用程序中的組件擁有相同的優先級。這一點非常重要,如果進程僅僅只是擁有BroadReceiver(一個普遍的情況是用戶從不或者是最近沒有和它進行交互),因此一旦它從onReceive()方法中返回時,系統就會認爲進程是空的並且主動的殺死它,以便這些資源可以被其他重要的進程利用。

這意味着對於耗時的操作,可以採用將Service和BroadcastReceiver結合使用以確保執行這個操作的進程在整個執行過程中都保持激活狀態。

發佈了85 篇原創文章 · 獲贊 67 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章