無序廣播(Normal broadcasts):無序且並行執行廣播
有序廣播(Ordered broadcasts):有序地一個接一個執行廣播
當通過意圖發送廣播時,無論BroadcastReceiver定義在當前應用還是其他應用中,只要BroadcastReceiver對此意圖感興趣(如:匹配Action),就會得到執行。
有序廣播和無序廣播默認都是運行在UI線程中的,當BroadcastReceiver在10秒內沒有執行完畢,Android會認爲該程序無響應,所以在BroadcastReceiver裏不能做一些比較耗時的操作,否則會彈出ANR(Application No Response)的對話框。如果需要完成一項比較耗時的工作,應該通過Intent發送給Service,由Service來完成,而不是使用子線程的方法來解決,因爲BroadcastReceiver的生命週期很短(在onReceive()執行後BroadcastReceiver的實例就會被銷燬),子線程可能還沒有結束BroadcastReceiver就先結束了。如果BroadcastReceiver結束了,它的宿主進程還在運行,那麼子線程還會繼續執行。但宿主進程此時很容易在系統需要內在時被優先殺死。因爲它屬於空進程(沒有任何活動組件的進程)。
下面分別講解這兩種廣播
無序廣播:
示例中FirstBroadcastReceiver和SecondBroadcastReceiver在同一個應用中,ThirdBroadcastReceiver在另一個應用中。
他們的執行順序是不可預知的。
應用A中代碼:
定義兩個BroadcastReceiver
public class FirstBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i("CDH", "FirstBroadcastReceiver msg:"+intent.getStringExtra("msg"));
}
}
public class SecondBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i("CDH", "SecondBroadcastReceiver msg:"+intent.getStringExtra("msg"));
}
}
AndroidManifest.xml中配置BroadcastReceiver
<receiver android:name=".FirstBroadcastReceiver">
<intent-filter>
<action android:name="com.improve.broadcast"/>
</intent-filter>
</receiver>
<receiver android:name=".SecondBroadcastReceiver">
<intent-filter>
<action android:name="com.improve.broadcast"/>
</intent-filter>
</receiver>
在一個名爲BroadcastReceiverDemo的Activity中定義一個Button,點擊事件如下
new OnClickListener() {
@Override
public void onClick(View button) {
//發送廣播
Intent intent = new Intent("com.improve.broadcast");
intent.putExtra("msg", "I am BroadcastReceiverDemo Activity");
sendBroadcast(intent);
}
}
應用B中代碼:
public class ThirdBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i("CDH", "ThirdBroadcastReceiver msg:"+intent.getStringExtra("msg"));
}
}
AndroidManifest.xml中配置BroadcastReceiver
<receiver android:name=".ThirdBroadcastReceiver">
<intent-filter>
<action android:name="com.improve.broadcast"/>
</intent-filter>
</receiver>
運行結果
有序廣播:
通過android:priority="N"設置廣播執行順序(N的取值-1000到1000),優先級高的廣播先執行。(這裏先執行SecondBroadcastReceiver再執行FirstBroadcastReceiver)
在前一個執行的廣播中設置結果值,傳給下一個廣播。也可以通過BroadcastReceiver.abortBroadcast()終止廣播,後面的廣播接收器不會得到執行。
定義兩個BroadcastReceiver
public class FirstBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i("CDH", "FirstBroadcastReceiver msg:"+intent.getStringExtra("msg"));
Bundle mBundle = this.getResultExtras(false);//true:前一個廣播沒有結果時創建新的Bundle;false:不創建Bundle
if (mBundle == null) {
Log.i("CDH", "沒有獲取到前一個運行的廣播返回的數據");
} else {
Log.i("CDH", "前一個運行的廣播返回的數據爲:" + mBundle.getString("msg"));
}
}
}
public class SecondBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i("CDH", "SecondBroadcastReceiver msg:"+intent.getStringExtra("msg"));
Bundle bundle = new Bundle();
bundle.putString("msg", "SecondBroadcastReceiver");
setResultExtras(bundle);
}
}
AndroidManifest.xml中配置BroadcastReceiver
<receiver android:name=".FirstBroadcastReceiver">
<intent-filter android:priority="1">
<action android:name="com.improve.broadcast"/>
</intent-filter>
</receiver>
<receiver android:name=".SecondBroadcastReceiver">
<intent-filter android:priority="2">
<action android:name="com.improve.broadcast"/>
</intent-filter>
</receiver>
在一個名爲BroadcastReceiverDemo的Activity中定義一個Button,點擊事件如下
new OnClickListener() {
@Override
public void onClick(View button) {
//發送廣播
Intent intent = new Intent("com.improve.broadcast");
intent.putExtra("msg", "BroadcastReceiverDemo");
sendOrderedBroadcast(intent, null);
}
}
運行結果