一般/有序 广播(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 就中断了。
 
                    
                
 
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号