Android系統的四大組件還有一種就是BroadcastReceiver,這種組件本質上就是全局監聽器,用於接收程序(用戶開發的程序和系統內建的程序)所發出的Broadcast Intent。
Broadcast被分爲如下兩種:
- 正常廣播 Normal broadcasts(用 Context.sendBroadcast()發送):是完全異步的,可以在同一時刻被所有接受者接收到,消息傳遞的效率比較高,但缺點是接收者不能將處理結果傳遞給下一個接收者,並且無法終止Broadcast Intent的傳播。
- 有序廣播 Ordered broadcasts(用 Context.sendOrderedBroadcast()發送):所謂有序,就是每個receiver執行後可以傳播到下一個receiver,也可以完全中止傳播,在代碼中寫入abortBroadcast();即可。優先級別聲明在<intent-filter.../>元素的android:priority屬性中,數越大優先級別越高,取值範圍爲-1000~1000。優先接到Broadcast的接收者可以通過setResultExtra(Bunble)方法將處理結果存入Broadcast中,然後傳給下一次接收者。下一個接收者通過代碼Bundle
bundle = getResuleExtras(true)獲取上一級接收者存入的數據。(String data = bundle.getString("data");)
通過sendBroadcast()來發送廣播:
1.新建BroadcastReceiver文件MyReceiver:
MainActivity的代碼:
public class MainActivity extends ActionBarActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btgb).setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btgb:
Intent intent = new Intent();
intent.setAction("songsong.com.broadcastreceivertext.intent.action.MyReceiver");
sendBroadcast(intent);
break;
}
}
}
MyReceiver.java文件內容:
public class MyReceiver extends BroadcastReceiver {
public MyReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("MyReceiver");
}
}
當符合該MyReceiver的廣播出現時,onReceive方法將會被觸發,從而在該方法中顯示消息。在AndroidManifest中application定義
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name:"songsong.com.broadcastreceivertext.intent.action.MyReceiver"/>
</intent-filter>
</receiver>
上面發送廣播的程序中指定發送廣播時所用的Intent的Action爲songsong.com.broadcastreceivertext.intent.action.MyReceiver
-----------------------------------------------------
通過sendOrderedBroadcast()來發送廣播:
接下來是一個發送有序廣播的示例,Activity界面上只有一個按鈕,用於發送一條有序廣播:
MyReceiver.java文件內容:
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btnsend).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();//創建Intent對象
intent.setAction("songsong.com.broadcast_orderd.intent.action.MyReceiver");
intent.putExtra("msg", "簡單的第1條信息");
sendOrderedBroadcast(intent, null); //發送有序廣播,null爲權限
}
});
}
程序中指定了Intent的Action屬性,再調用sendOrderedBroadcast()方法來發送有序廣播,它會按優先級依次觸發每個BroadcastReceiver的OnReceive()方法。
接下來定義第一個BroadcastReceiver。
public class MyReceiver extends BroadcastReceiver {
public MyReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, intent.getAction() + intent.getStringExtra("msg"), Toast.LENGTH_SHORT).show();
Bundle bundle = new Bundle();//創建一個Bundle對象並存入信息
bundle.putString("data1", "這是第一個MyReceiver發出的信息");
setResultExtras(bundle); //將Bundle放入結果中
//abortBroadcast();//取消Broadcast繼續傳播
}
}
上面BroadcastReceiver不僅處理了所接收到的消息,而且還處理結果中存入的key爲“data1”的消息,這個消息將可以被第二個BroadcastReceiver解析出來。
如果abortBroadcast();代碼執行,Broadcast將會終止傳播,那麼優先級別比MyReceiver 低的BroadcastReceiver將不會被觸發
在AndroidManifest.xml文件中部署該BroadcastReceiver,並指定優先級爲20,如下:
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true" >
<intent-filter android:priority="20" >
<action android:name="songsong.com.broadcast_orderd.intent.action.MyReceiver" />
</intent-filter>
</receiver>
接下來爲程序提供第二個BroadcastReceiver,這個將會解析前一個BroadcastReceiver所存入的key爲data1的消息。如下:
public class MyReceiver2 extends BroadcastReceiver {
public MyReceiver2() {
}
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = getResultExtras(true);
String data = bundle.getString("data1");//解析前一個<span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;">BroadcastReceiver</span></span></span>所存入的key爲data1的消息
Toast.makeText(context, data, Toast.LENGTH_SHORT).show();
}
}
在AndroidManifast.xml文件中配置該BroadcastReceiver,並指定優先級別爲19,如下:
<receiver
android:name=".MyReceiver2"
android:enabled="true"
android:exported="true" >
<intent-filter android:priority="19" >
<action android:name="songsong.com.broadcast_orderd.intent.action.MyReceiver" />
</intent-filter>
</receiver>
MyReceiver的優先級更高點,MyReceiver2略低, abortBroadcast();被註釋的情況下,那麼程序會先運行MyReceiver再到MyReceiver2。如果abortBroadcast();沒有被註釋的話,程序只運行MyReceiver。
——————————————————————————
爲BroadcastReceiver指定Intent,有兩種方式:
1、使用代碼進行指定,調用BroadcastReceiver的context的registerReceiver(BroadcastReceiver receiver,filter)方法指定,代碼如下:
ActivityReceiver activityReceiver = new ActivityReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("songsong.com.broadcast_orderd.intent.action.MyReceiver");
registerReceiver(activityReceiver, filter); //註冊廣播
2、在AndroidManifest.xml文件中配置。如下:
<receiver
android:name=".MyReceiver">
<intent-filter>
<action android:name="songsong.com.broadcast_orderd.intent.action.MyReceiver" />
</intent-filter>
</receiver>
--------------------------------------------------
在BroadCast 中儘量不要處理太多邏輯問題,建議複雜的邏輯交給Activity 或者 Service 去處理。