標籤:
本文主要介紹BroadcastReceiver的概念、使用、生命週期、安全性、分類、特殊的BroadcastReceiver(本地、粘性、有序、粘性有序廣播)。
範例程式碼見BroadcastReceiverDemo,樣本APK見:TrineaAndroidDemo.apk。
1、概念介紹及兩種註冊方式的區別
BroadcastReceiver作為Android四大組件之一,不像Activity,沒有可顯示的介面。BroadcastReceiver包括兩個概念,廣播寄件者和廣播接收者(Receiver),這裡的廣播實際就是指Intent,程式可以自己發送廣播自己接收,也可以接受系統或其他應用的廣播或是發送廣播給其他應用程式。
寄件者可以通過類似Context.sendBroadcast介面發送廣播,接收者通過Context.registerReceiver()動態註冊或在AndroidManifest.xml檔案中通過<receiver>標籤靜態註冊,註冊完成後,當寄件者發送某個廣播時系統會將發送的廣播(Intent)與系統中所有註冊的合格接收者(Receiver) 的IntentFilter進行匹配,若匹配成功則執行相應接收者的onReceive函數,匹配規則見Intent和IntentFilter的匹配規則。
關於registerReceiver動態註冊和通過<receiver>標籤靜態註冊廣播的區別如下:
a.對bindService的調用,<receiver>註冊的廣播,在onReceive結束後廣播即不存在,所以不能在其中給自己非同步傳遞結果,如bindService而只能使用startService,如果想跟service互動可使用peekService。
b. 手動控制。registerReceiver為動態註冊,自己可以手動註冊或是取消註冊;<receiver>標籤為靜態註冊,由系統開機時自動掃描註冊,所以無法手動控制,開機一直運行中。
c. 資源消耗不同。registerReceiver可以手動控制,所以適當的註冊和取消註冊能節省系統資源,<receiver>標籤系統開機後一直有效。
d. 有效期間不同。通過registerReceiver註冊的BroadcastReceiver在對其進行註冊的Context對象"銷毀"了或者調用了unregisterReceiver方法時也就失效了,而通過<receiver>標籤註冊的BroadcastReceiver只要應用程式沒有被刪除就一直有效。
e. 對registerReceiver函數的調用許可不同。通過registerReceiver註冊的BroadcastReceiver在其onReceive函數中可以再次調用某個Context的registerReceiver函數,而通過<receiver>標籤註冊的BroadcastReceiver不允許再調用某個Context的registerReceiver函數 。
f. 使用方式不同。對於自己發送和接受的廣播可以通過registerReceiver註冊,對於系統常用廣播的接收通常用<receiver>標籤註冊。
2、使用舉例
public class BroadcastReceiverDemo extends Activity { private final static String ACTION_SEND = "com.trinea.android.demo.BroadcastReceiverDemo.sendBroadcast"; private final static String MSG_KEY = "msg"; private MyBroadcastReceiver receiver; private Button sendBtn; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.broadcast_receiver_demo); receiver = new MyBroadcastReceiver(); sendBtn = (Button)findViewById(R.id.sendBroadcast); sendBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { sendBtn.setText("發送中"); sendBtn.setClickable(false); Intent i = new Intent(ACTION_SEND); i.putExtra(MSG_KEY, "好聲音馬上開始了啦"); sendBroadcast(i); } }); } @Override public void onPause() { super.onPause(); unregisterReceiver(receiver); } @Override public void onResume() { super.onResume(); registerReceiver(receiver, new IntentFilter(ACTION_SEND)); } public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { sendBtn.setText("發送廣播"); sendBtn.setClickable(true); Toast.makeText(context, intent.getStringExtra(MSG_KEY), Toast.LENGTH_SHORT).show(); } }}
R.layout.broadcast_receiver_demo的內容為一個簡單的id為sendBroadcast的Button
從上面代碼可以看到我們
a. 建立BroadcastReceiver只需要繼承BroadcastReceiver並重寫OnReceiver函數,加上自己的處理邏輯。
b. 通過registerReceiver註冊廣播,通過unregisterReceiver取消註冊廣播,通過sendBroadcast發送廣播。
其中註冊和取消註冊廣播放在了OnResume和OnPause函數中可以有效節省系統消耗。如果希望廣播一直運行中可以在Activity的OnCreate函數中註冊,在OnDestrory函數中取消註冊。
這裡的MyBroadcastReceiver也可以在AndroidManifest.xml檔案中靜態註冊,這樣程式安裝後便一直運行中。比如希望接收到簡訊到來時的廣播,如下:
<receiver android:name="MyBroadcastReceiver"> <intent-filter> <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter></receiver>
【轉】Android BroadcastReceiver介紹