一般/有序 广播(Broadcast)

广播的分类标准不同,分类的结果也不同。如根据广播的接收顺序划分,有 Normal broadcasts(一般广播)和 Ordered broadcasts(有序广播);根据发送广播的来源不同可以分为自定义广播系统广播

Normal broadcasts(一般广播)是通过 Context.sendBroadcast 发出的,采用异步机制,匹配此广播的接收器都会响应,且响应的顺序不确定,无先后之分。这种方式对于利用广播而言,效率比较高,但各广播接收器无法改造广播信息,且无法停止该广播。

Ordered broadcasts(有序广播)是通过 Context.sendOrderedBroadcast 发出的,每次只有一个接收器收到,与此广播匹配的接收器将按照先后顺序响应,先后顺序由广播接收器的优先级决定。每个接收器可以处理它所收到的广播数据,并将处理的数据传递给下一个接收器;也可以将所收到的广播扔掉,从而停止本次广播。广播被停止后,其他接收器将无法再响应。如果遇到优先级相同的广播接收器,仍按照随机方式响应。

有序广播的优先级取值范围在 -1000 ~ 1000 之间,数值越大,优先级越高。使用 sendOrderedBroadcast 方法发送有序广播时,需要一个权限参数,如果为 null 则表示不要求接受者声明指定的权限,如果不为 null 则表示接受者若要接收此广播,需要声明指定权限。

Android 系统的短信就是有序广播的形式,如果开放一个拦截垃圾短信功能的应用程序,当短信到来时,可以先接收短信广播,必要时终止广播传递,这样的应用程序就必须声明接收短信的权限。

BroadcastReceiver 中的常用方法

1、abortBroadcast();  终止广播。只能终止有序广播,对应一般广播无效。

2、getResultExtras(boolean makeMap); 返回值为 Bundle,获取结果集数据。

3、setResultExtras(Bundle extras); 设置结果集。

4、isOrderedBroadcast(); 判断当前广播是否是有序广播。

5、onReceive(Context context, Intent intent); 抽象方法,实现广播接收器,必须实现该方法,接收到广播时执行该方法。

 1 public class MyReceiver1 extends BroadcastReceiver {
 2     
 3     static final String TAG = "Tag";
 4     
 5     @Override
 6     public void onReceive(Context context, Intent intent) {
 7         
 8         // 获取随 Intent 到达的数据
 9         String msg = intent.getStringExtra("msg");
10         Log.i(TAG, "接收器 MyReceiver1,收到信息 》" + msg);
11         
12         Bundle b = new Bundle();
13         b.putString("msg", msg + "@ from MyReceiver1");
14         setResultExtras(b);
15     }
16 }
MyReceiver1 接收器获取广播中的数据,输出到日志,创建 Bundle,用于存放数据。将从广播中获取的数据修改,在原来内容的基础上连接 @ from MyReceiver1,并将新数据放入结果集
 1 public class MyReceiver2 extends BroadcastReceiver {
 2     
 3     static final String TAG = "Tag";
 4     
 5     @Override
 6     public void onReceive(Context context, Intent intent) {
 7         
 8         String msg = getResultExtras(true).getString("msg");
 9         Log.i(TAG, "接收器 MyReceiver2,收到信息 》" + msg);
10         
11         Bundle b = new Bundle();
12         b.putString("msg", msg + "@ from MyReceiver2");
13         setResultExtras(b);
14         abortBroadcast();    // 终止广播
15     }
16 }

 MyReceiver2 接收器在提取数据时,是从结果集中获取的,并输出到日志。然后重建 Bundle,将获取的数据再次修改,追加 @ from MyReceiver2,放入结果集。调用 abortBroadcast 方法(这是 .BroadcastReceiver 中声明的 final 方法),终止广播。

 1 public class MyReceiver3 extends BroadcastReceiver {
 2     
 3     static final String TAG="Tag";
 4     
 5     @Override
 6     public void onReceive(Context context, Intent intent) {
 7         
 8         // 获取结果集的数据
 9         String msg = getResultExtras(true).getString("msg");
10         Log.i(TAG, "接收器,收到信息 》" + msg);
11     }
12 }

MyReceiver3 接收器获取结果集中的数据,并输出到日志。

 1     @Override
 2     public void onCreate(Bundle savedInstanceState) {
 3         super.onCreate(savedInstanceState);
 4         
 5         setContentView(R.layout.main);
 6         b = (Button) findViewById(R.id.button1);
 7         b.setOnClickListener(new OnClickListener(){
 8             
 9             @Override
10             public void onClick(View v) {
11                 
12                 Intent intent = new Intent("com.freshen.code.MyReceiver");
13                 intent.putExtra("msg", "原始广播数据");
14                 sendOrderedBroadcast(intent, null);        // 发出有序广播
15                 Log.i("Tag", "有序广播已发出");
16             }}
17         );
18     }

sendOrderedBroadcast(intent, receiverPermission) 方法中两个参数的含义如下:

1、intent:打算发出的广播,与此广播匹配的所有接收器将会响应;

2、receiverPermission:权限字符串,可以引用系统值,也可以是自己定义的,一旦设定权限,则接收器必须声明该权限才能收到广播;如果为 null,则接收广播不需要权限。

 1 @Override
 2     protected void onStart() {
 3         super.onStart();
 4         
 5         // 注册监听器
 6         br1 = new MyReceiver1();
 7         IntentFilter if1 = new IntentFilter("com.freshen.code.MyReceiver");
 8         if1.setPriority(1000);     // 设定优先级权限
 9         registerReceiver(br1, if1);
10         //
11         br2 = new MyReceiver2();
12         if1.setPriority(999);     // 设定优先级权限
13         registerReceiver(br2, if1);
14         //
15         br3 = new MyReceiver3();
16         if1.setPriority(998);     // 设定优先级权限
17         registerReceiver(br3, if1);
18     }
19     
20     @Override
21     protected void onStop() {
22         super.onStop();
23         
24         if(br1 != null)    unregisterReceiver(br1);
25         if(br2 != null)    unregisterReceiver(br2);
26         if(br3 != null)    unregisterReceiver(br3);
27     }    

动态注册广播接收器,MyReceiver1 的权限为1000,依次减小。根据有序广播的特性,会从优先级高的接收器依次传递给优先级低的接收器。但由于在 MyReceiver2 中执行了 abortBroadcast,本次广播在 MyReceiver2 就中断了。

 

posted @ 2015-05-26 15:05  壬子木  阅读(866)  评论(0)    收藏  举报