Android:廣播BroadcastReceiver

來源:互聯網
上載者:User

 什麼是BroadcastReceiver?

  BroadcastReceiver,廣播接收者,它是一個系統全域的監聽器,用於監聽系統全域的Broadcast訊息,所以它可以很方便的進行系統組件之間的通訊。

  BroadcastReceiver雖然是一個監聽器,但是它和之前用到的OnXxxListener不同,那些只是程式層級的監聽器,運行在指定程式的所在進程中,當程式退出的時候,OnXxxListener監聽器也就隨之關閉了,但是BroadcastReceiver屬於系統級的監聽器,它擁有自己的進程,只要存在與之匹配的Broadcast被以Intent的形式發送出來,BroadcastReceiver就會被啟用。

  雖然同屬Android的四大組件,BroadcastReceiver也有自己獨立的聲明周期,但是和Activity、Service又不同。當在系統註冊一個BroadcastReceiver之後,每次系統以一個Intent的形式發布Broadcast的時候,系統都會建立與之對應的BroadcastReceiver廣播接收者執行個體,並自動觸發它的onReceive()方法,當onReceive()方法被執行完成之後,BroadcastReceiver的執行個體就會被銷毀。雖然它獨自享用一個單獨的進程,但也不是沒有限制的,如果BroadcastReceiver.onReceive()方法不能在10秒內執行完成,Android系統就會認為該BroadcastReceiver對象無響應,然後彈出ANR(Application No Response)對話方塊,所以不要在BroadcastReceiver.onReceive()方法內執行一些耗時的操作。

  如果需要根據廣播內容完成一些耗時的操作,一般考慮通過Intent啟動一個Service來完成該操作,而不應該在BroadcastReceiver中開啟一個新線程完成耗時的操作,因為BroadcastReceiver本身的生命週期很短,可能出現的情況是子線程還沒有結束,BroadcastReceiver就已經退出的情況,而如果BroadcastReceiver所在的進程結束了,該線程就會被標記為一個空線程,根據Android的記憶體管理原則,在系統記憶體緊張的時候,會按照優先順序,結束優先順序低的線程,而空線程無異是優先順序最低的,這樣就可能導致BroadcastReceiver啟動的子線程不能執行完成。

   BroadcastReceiver的種類

  上面提到,當系統以一個Intent的形式發送一個Broadcast出去之後,所有與之匹配的BroadcastReceiver都會被執行個體化,但是這裡是有區別的,根據Broadcast的傳播方式區別,在系統中有如下兩種Broadcast:

  • 普通廣播:Normal Broadcase,它是完全非同步,也就是說,在邏輯上,當一個Broadcast被發出之後,所有的與之匹配的BroadcastReceiver都同時接收到Broadcast。優點是傳遞效率比較高,但是也有缺點,就是一個BroadcastReceiver不能影響其他響應這條Broadcast的BroadcastReceiver。
  • 有序廣播:Ordered Broadcast,它是同步執行的,也就是說有序廣播的接收器將會按照預先聲明的優先順序依次接受Broadcast,是鏈式結構,優先順序越高(-1000~1000),越先被執行。因為是順序執行,所有優先順序高的接收器,可以把執行結果傳入下一個接收器中,也可以終止Broadcast的傳播(通過abortBroadcast()方法),一旦Broadcast的傳播被終止,優先順序低於它的接收器就不會再接收到這條Broadcast了。

  雖然系統存在兩種類型的Broadcast,但是一般系統發送出來的Broadcast均是有序廣播,所以可以通過優先順序的控制,在系統內建的程式響應前,對Broadcast提前進行響應。這就是市場上一些攔截器類(如:簡訊攔截器、電話攔截器)的軟體的原理。 

 如何發送一個廣播

  上面已經介紹了系統中兩種不同的Broadcast,而根據Broadcast傳播的方式,Context提供了不同的方法來發布它們:

  • sendBroadcast():發送普通廣播。
  • sendOrderedBroadcast():發送有序廣播。

  以上兩個方法都有多個重載方法,根據不同的情境使用,最簡單的莫過於直接傳遞一個Intent來發送一個廣播。

 如何使用BroadcastReceiver

   BroadcastReceiver本質上還是一個監聽器,所以使用BroadcastReceiver的方法也是非常簡單,只需要繼承BroadcastReceiver,在其中重寫onReceive(Context context,Intent intent)即可。一旦實現了BroadcastReceiver,並部署到系統中後,就可以在系統的任何位置,通過sendBroadcast、sendOrderedBroadcast方法發送Broadcast給這個BroadcastReceiver。

  但是僅僅繼承BroadcastReceiver和實現onReceive()方法是不夠的,同為Android系統組件,它也必須在Android系統中註冊,註冊一個BroadcastReceiver有兩種方式:

  • 在代碼中使用Content.registerReceiver(BroadcastReceiver receiver, IntentFilter filter)進行註冊,在使用完畢使用Content.unregisterReceiver(BroadcastReceiver receiver)方法進行登出。
  • 使用資訊清單檔AndroidManifest.xml註冊,在<application/>節點中,使用<receiver/>節點註冊,並用android:name屬性中指定註冊的BroadcastReceiver對象,一般還會通過<Intent-filter/>指定<action/>和<category/>,並在<Intent-filter/>節點中通過android:priority屬性設定BroadcastReceiver的優先順序,在-1000~1000範圍內,數值越到優先順序越高。

   雖然Android系統提供了兩種方式註冊BroadcastReceiver,但是一般在實際開發中,還是會使用資訊清單檔進行註冊: 

1         <receiver android:name="cn.bgxt.Broadcastdemo.Basic.BasicBroadcast">2             <intent-filter android:priority="100">3                 <action android:name="cn.bgxt.Broadcastdemo.Basic.broadcast"/>4             </intent-filter>            5         </receiver>

   下面通過一個簡單的樣本,講解一下BroadcastReceiver的聲明,以及如何向這個BroadcastReceiver發送訊息。

   首先先聲明一個BroadcastReceiver,BasicBroadcast.java:

 1 package cn.bgxt.Broadcastdemo.Basic; 2  3 import android.content.BroadcastReceiver; 4 import android.content.Context; 5 import android.content.Intent; 6 import android.widget.Toast; 7  8 public class BasicBroadcast extends BroadcastReceiver { 9 10     @Override11     public void onReceive(Context context, Intent intent) {12         Toast.makeText(context,13                 "接收到Broadcast,訊息為:" + intent.getStringExtra("msg"),14                 Toast.LENGTH_SHORT).show();15     }16 }

   再聲明一個Activity,用於發送Broadcast:BasicActivity.java: 

 1 package cn.bgxt.Broadcastdemo.Basic; 2  3 import com.bgxt.datatimepickerdemo.R; 4  5 import android.app.Activity; 6 import android.content.Intent; 7 import android.os.Bundle; 8 import android.view.View; 9 import android.widget.Button;10 11 public class BasicActivity extends Activity {12     Button btnBasicSendNormal, btnBasicSendOrdered;13 14     @Override15     protected void onCreate(Bundle savedInstanceState) {16         super.onCreate(savedInstanceState);17         setContentView(R.layout.activity_basic);18 19         btnBasicSendNormal = (Button) findViewById(R.id.btnBasicSendNormal);20         btnBasicSendOrdered = (Button) findViewById(R.id.btnBasicSendOrdered);21         btnBasicSendNormal.setOnClickListener(new View.OnClickListener() {22 23             @Override24             public void onClick(View v) {25                 Intent broadcast=new Intent();26                 broadcast.setAction("cn.bgxt.Broadcastdemo.Basic.broadcast");27                 broadcast.putExtra("msg", "這是一個普通廣播");28                 sendBroadcast(broadcast);29             }30         });31 32         btnBasicSendOrdered.setOnClickListener(new View.OnClickListener() {33 34             @Override35             public void onClick(View v) {36                 Intent broadcast=new Intent();37                 broadcast.setAction("cn.bgxt.Broadcastdemo.Basic.broadcast");38                 broadcast.putExtra("msg", "這是一個有序廣播");39                 sendOrderedBroadcast(broadcast, null);40             }41         });42     }43 }

  效果展示:

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.