官方解讀BroadcastReceiver

來源:互聯網
上載者:User

綜述
   BroadcastReceiver是接收從sendBroadcast()發出的intent的基類。你可以通過Context.registerReceiver()方法在代碼中動態註冊一個BroadcastReceiver的執行個體,也可以通過再AndroidManifest.xml檔案中用<receiver>標籤來靜態聲明。
   注意:如果你實在Activity.onResume()方法中註冊的一個receiver,那麼你必須在Activity.onPause()方法中進行登出。(當一個activity處於暫停狀態是不會接收intents的,並且這樣做也可以減小系統不必要的開銷)。不要在Activity.onSaveInstanceState()方法中登出receiver,因為activity從棧中恢複的時候並不會調用這個方法了。
   可以接收的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,這裡的Intent broadcast機制和那些通過Context.startActivity()方法來啟動activity的intent是完全獨立的。一個BroadcastReceiver是沒辦法觀察和捕獲一個用於啟動activity的intent的;同樣的,當你通過intent來發出broadcast時,你也不可能(通過這個intent)找到或者啟動一個activity的。這兩種操作是完全不同的:通過一個intent來啟動一個activity是一個前台操作,會改變使用者當前互動的對象;而通過intent來發出broadcast是一個後台操作,使用者經常是察覺不到的。
   BroadcastReceiver類(通過一個manifest的<receiver>標籤作為一個組件啟動)是應用程式全域聲明周期重要的一部分。
  
討論的主題
   1、Receiver的生命週期
   2、許可權
   3、進程的生命週期
  
開發人員指南
   更詳細的關於如何擷取和解析一個Intent的內容,請詳見Intents and Intent Filters開發人員指南
  
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結合使用以確保執行這個操作的進程在整個執行過程中都保持啟用狀態。


摘自 chenlong12580的專欄

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.