想要全面瞭解廣播,須知以下幾點
1、創建廣播接收者類
繼承BroadcastReceiver,重寫onReceive方法, 以MyReceiver extends BroadcastReceiver爲例子
public void onReceive(Context context, Intent intent){}
---------------------------------------------------------------------------------------------
2、靜態註冊廣播or動態註冊廣播
---------------------------------------------------------------------------------------------
2.1 靜態註冊廣播
靜態註冊
靜態註冊是在AndroidManifest.xml文件中配置的,我們就來爲MyReceiver註冊一個廣播地址:
-
<receiver android:name=".MyReceiver">
-
<intent-filter>
-
<action android:name="android.intent.action.MY_BROADCAST"/>
-
<category android:name="android.intent.category.DEFAULT" />
-
</intent-filter>
-
</receiver>
配置了以上信息之後,只要是android.intent.action.MY_BROADCAST這個地址的廣播,MyReceiver都能夠接收的到。注意,這種方式的註冊是常駐型的,也就是說當應用關閉後,如果有廣播信息傳來,MyReceiver也會被系統調用而自動運行。
2.2 動態註冊廣播
動態註冊
動態註冊需要在代碼中動態的指定廣播地址並註冊,通常我們是在Activity或Service註冊一個廣播,下面我們就來看一下注冊的代碼:
-
MyReceiver receiver = new MyReceiver();
-
-
IntentFilter filter = new IntentFilter();
-
filter.addAction("android.intent.action.MY_BROADCAST");
-
-
registerReceiver(receiver, filter);
注意,registerReceiver是android.content.ContextWrapper類中的方法,Activity和Service都繼承了ContextWrapper,所以可以直接調用。在實際應用中,我們在Activity或Service中註冊了一個BroadcastReceiver,當這個Activity或Service被銷燬時如果沒有解除註冊,系統會報一個異常,提示我們是否忘記解除註冊了。所以,記得在特定的地方執行解除註冊操作:
-
@Override
-
protected void onDestroy() {
-
super.onDestroy();
-
unregisterReceiver(receiver);
-
}
執行這樣行代碼就可以解決問題了。注意,這種註冊方式與靜態註冊相反,不是常駐型的,也就是說廣播會跟隨程序的生命週期。
------------------------------------------------------------------------------
3、我們可以根據以上任意一種方法完成註冊,當註冊完成之後,這個接收者就可以正常工作了。我們可以用以下方式向其發送一條廣播:
-
public void send(View view) {
-
Intent intent = new Intent("android.intent.action.MY_BROADCAST");
-
intent.putExtra("msg", "hello receiver.");
-
sendBroadcast(intent);
-
}
注意,sendBroadcast也是android.content.ContextWrapper類中的方法,它可以將一個指定地址和參數信息的Intent對象以廣播的形式發送出去。
----------------------------------------------------------------------------
4、普通廣播和有序廣播
4.1 Normal Broadcast(普通廣播):Normal Broadcast是完全異步的,可以在同一時刻(邏輯上)被所有接收者接收到,消息傳遞的效率比較高。但缺點是接受者不能將處理結果傳遞給下一個接收者,並且無法終止Broadcast Intent的廣播。
4.2 Ordered Broadcast(有序廣播):Ordered Broadcast的接收者將按預先聲明的優先級依次接受Broadcast。如:A的級別高於B、B的級別高於C,那麼Broadcast先傳給A,再傳給B,最後傳給C。優先級別聲明在<intent-filter.../>元素的android:priority屬性中,數越大優先級別越高,取值範圍爲-1000-1000,優先級別也可以調用IntentFilter對象的setPriority()進行設置。OrderedBroadcast接收者可以終止Broadcast
Intent的傳播,BroadcastIntent的傳播一旦終止,後面的接收者就無法接收到Broadcast。另外,OrderedBroadcast的接收者可以將數據傳遞給下一個接收者。如:A得到Broadcast後,可以往它的結果對象中存入數據,當Broadcast傳給B時,B可以從A的結果對象中得到A存入的數據。
4.3 context提供的如下兩個方法用於發送廣播:
sendBroadcast():發送Normal Broadcast
sendOrderedBroadcast():發送OrderedBroadcast。
4.4 對於OrderedBroadcast而言,系統會根據接收者生命的優先級別順序逐個執行接收者,優先接收到Broadcast的接收者可以終止Broadcast,調用BroadcastReceiver的abortBroadcast()方法即可終止Broadcast。如果Broadcast被前面的接收者終止,後面的接收者就再也無法獲取到Broadcast。
4.5 不僅如此,對於OrderBroadcast而言,優先接收到Broadcast的接收者可以通過setResultExtras(Bundle)方法將處理結果存入Broadcast中,然後傳給下一個接收者,下一個接收者通過代碼: Bundle bundle=getResultExtras(true)可以獲取上一個接收者存入的數據。
有序廣播示例
如下:
-
package com.scott.receiver;
-
-
import android.content.BroadcastReceiver;
-
import android.content.Context;
-
import android.content.Intent;
-
import android.os.Bundle;
-
import android.util.Log;
-
-
public class FirstReceiver extends BroadcastReceiver {
-
-
private static final String TAG = "OrderedBroadcast";
-
-
@Override
-
public void onReceive(Context context, Intent intent) {
-
String msg = intent.getStringExtra("msg");
-
Log.i(TAG, "FirstReceiver: " + msg);
-
-
Bundle bundle = new Bundle();
-
bundle.putString("msg", msg + "@FirstReceiver");
-
setResultExtras(bundle);
-
}
-
-
}
-
public class SecondReceiver extends BroadcastReceiver {
-
-
private static final String TAG = "OrderedBroadcast";
-
-
@Override
-
public void onReceive(Context context, Intent intent) {
-
String msg = getResultExtras(true).getString("msg");
-
Log.i(TAG, "SecondReceiver: " + msg);
-
-
Bundle bundle = new Bundle();
-
bundle.putString("msg", msg + "@SecondReceiver");
-
setResultExtras(bundle);
-
}
-
-
}
-
public class ThirdReceiver extends BroadcastReceiver {
-
-
private static final String TAG = "OrderedBroadcast";
-
-
@Override
-
public void onReceive(Context context, Intent intent) {
-
String msg = getResultExtras(true).getString("msg");
-
Log.i(TAG, "ThirdReceiver: " + msg);
-
}
-
-
}
我們注意到,在FirstReceiver和SecondReceiver中最後都使用了setResultExtras方法將一個Bundle對象設置爲結果集對象,傳遞到下一個接收者那裏,這樣以來,優先級低的接收者可以用getResultExtras獲取到最新的經過處理的信息集合。
代碼改完之後,我們需要爲三個接收者註冊廣播地址,我們修改一下AndroidMainfest.xml文件:
-
<receiver android:name=".FirstReceiver">
-
<intent-filter android:priority="1000">
-
<action android:name="android.intent.action.MY_BROADCAST"/>
-
<category android:name="android.intent.category.DEFAULT" />
-
</intent-filter>
-
</receiver>
-
<receiver android:name=".SecondReceiver">
-
<intent-filter android:priority="999">
-
<action android:name="android.intent.action.MY_BROADCAST"/>
-
<category android:name="android.intent.category.DEFAULT" />
-
</intent-filter>
-
</receiver>
-
<receiver android:name=".ThirdReceiver">
-
<intent-filter android:priority="998">
-
<action android:name="android.intent.action.MY_BROADCAST"/>
-
<category android:name="android.intent.category.DEFAULT" />
-
</intent-filter>
-
</receiver>
我們看到,現在這三個接收者的<intent-filter>多了一個android:priority屬性,並且依次減小。這個屬性的範圍在-1000到1000,數值越大,優先級越高。
現在,我們需要修改一下發送廣播的代碼,如下:
-
public void send(View view) {
-
Intent intent = new Intent("android.intent.action.MY_BROADCAST");
-
intent.putExtra("msg", "hello receiver.");
-
sendOrderedBroadcast(intent, "scott.permission.MY_BROADCAST_PERMISSION");
-
}
注意,使用sendOrderedBroadcast方法發送有序廣播時,需要一個權限參數,如果爲null則表示不要求接收者聲明指定的權限,如果不爲null,則表示接收者若要接收此廣播,需聲明指定權限。這樣做是從安全角度考慮的,例如系統的短信就是有序廣播的形式,一個應用可能是具有攔截垃圾短信的功能,當短信到來時它可以先接受到短信廣播,必要時終止廣播傳遞,這樣的軟件就必須聲明接收短信的權限。
所以我們在AndroidMainfest.xml中定義一個權限:
-
<permission android:protectionLevel="normal"
-
android:name="scott.permission.MY_BROADCAST_PERMISSION" />
然後聲明使用了此權限:
-
<uses-permission android:name="scott.permission.MY_BROADCAST_PERMISSION" />
參考博文:http://blog.csdn.net/liuhe688/article/details/6955668