静态/动态注册 BroadcastReceiver 广播接收器

Android 系统中的广播实质上指的是发送 Intent,用于在应用程序之间传送消息,但与 Activity 中使用的 Intent 是不同的。Activity 中的 Intent 是在前台执行的,广播中的 Intent 是在后台执行的。BroadcastReceiver 是广播接收器,用于接收来自系统和应用程序中的广播。

广播可以来源于系统,成为系统广播,也可以在应用程序中发出广播。发送广播是使用 android.content.ContentWrapper 方法,Activity 和 Service 都继承自 ContextWrapper,因此可以在 Activity Service 中发出广播。

发送广播常用方法

1、sendBroadcast(Intent intent);  发送普通广播,匹配的 BroadcastReceiver 都会收到该广播,并执行 onReceiver 方法,如有多个 BroadcastReceiver 都匹配,则相应的先后顺序不确定。

2、sendOrderedBroadcast(Intent intent, String receiverPermission);  发送有序广播,匹配的 BroadcastReceiver 会收到该广播,当多个接收器都匹配时,根据注册时 IntentFilter 的优先级顺序响应。

3、sendStickyBroadcast(Intent intent);  发送粘性广播,已经注册的 BroadcastReceiver 匹配后,响应该广播;该广播的 Intent 会一直保持,在广播发出后,如有再注册的 BroadcastReceiver 也会接收到该条广播。广播发出后,如果不是粘性广播会很快的消失(约 10s)。

接收广播就需要注册 BroadcastReceiver,注册方式主要有静态注册和动态注册。

1、静态注册

静态注册就是在 Manifest 文件中,使用 <receiver> 标签配置。配置时需要使用 <intent-filter> 指明所接收的广播。静态注册的广播接收是常驻型的,即使当应用程序关闭,如果有匹配的广播来到,接收器也会响应。这类接收器多用于接收系统广播,如电话、短信等。

1         <!-- 声明接收器,并指明匹配动作 -->
2         <receiver android:name=".MyBroadcastReceiver">
3             <intent-filter >
4                 <action android:name="com.freshen.code.MyBroadcastReceiver" />
5                 <category android:name="android.intent.category.DEFAULT" />
6             </intent-filter>
7         </receiver>

新建类 MyBroadcastReceiver 继承 BroadcastReceiver,重写 onReceive 方法。对于 BroadcastReceiver 来说,只需要关注该方法,其他方法都被 final 修饰。

 1 public class MyBroadcastReceiver 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, "接收器收到信息 》" + msg);
11     }
12 }

发送广播 sendBroadcast(intent);

 1 @Override
 2     public void onClick(View arg0) {
 3         
 4         if(arg0.getId() == R.id.bc_bt01){
 5             //
 6             Intent intent = new Intent("com.freshen.code.MyBroadcastReceiver");
 7             intent.putExtra("msg","广播信息 : 随机数 " + rand.nextInt(100));
 8             // 发出广播
 9             // 匹配 com.freshen.code.MyBroadcastReceiver 动作的广播接收器将接受到该广播
10             sendBroadcast(intent);
11             Log.i(TAG, "广播已发出");
12         }

 

2、动态注册

动态注册广播接收器不需要借助配置文件,使用 ContextWrapper.registerReceiver(BroadcastReceiver receiver, IntentFilter filter) 执行动态注册,参数含义如下:

1、receiver:需要注册的广播接收器;

2、filter:广播接收器需要匹配的动作。

unregisterReceiver(BroadcastReceiver receiver) 取消动态注册,需要注意的是动态注册的广播接收器,在应用退出时需要解除注册,否则会抛出异常。根据应用的不同,需要开始注册和解除注册可以写在 Activity 或 Service 的相应生命周期方法中,比如在 onDestroy 方法中解除注册。

 1 public class MainActivity extends Activity implements OnClickListener {
 2     
 3     static final String TAG = "Tag";
 4     Button b1,b2,b3,b4;
 5     Random rand = new Random();
 6     MyBroadcastReceiver2 receiver2; // 广播接收器
 7     
 8     @Override
 9     public void onCreate(Bundle savedInstanceState) {
10         super.onCreate(savedInstanceState);
11         
12         setContentView(R.layout.main);
13         b1 = (Button) findViewById(R.id.bc_bt01);
14         b1.setOnClickListener(this);
15         b2 = (Button) findViewById(R.id.bc_bt02);
16         b2.setOnClickListener(this);
17         b3 = (Button) findViewById(R.id.bc_bt03);
18         b3.setOnClickListener(this);
19         b4 = (Button) findViewById(R.id.bc_bt04);
20         b4.setOnClickListener(this);
21     }
22     
23     @Override
24     public void onClick(View arg0) {
25         
26         if(arg0.getId() == R.id.bc_bt01){
27             //
28             Intent intent = new Intent("com.freshen.code.MyBroadcastReceiver");
29             intent.putExtra("msg","广播信息 : 随机数 " + rand.nextInt(100));
30             // 发出广播
31             // 匹配 com.freshen.code.MyBroadcastReceiver 动作的广播接收器将接受到该广播
32             sendBroadcast(intent);
33             Log.i(TAG, "广播已发出");
34         }
35         
36         if(arg0.getId() == R.id.bc_bt02){
37             // 注册广播接收器
38             receiver2 = new MyBroadcastReceiver2();
39             IntentFilter filter = new IntentFilter("com.freshen.code.MyBroadcastReceiver2");
40             registerReceiver(receiver2, filter);    // 执行注册
41             Log.i(TAG, "广播接收器已注册");
42         }else if(arg0.getId() == R.id.bc_bt03){
43             // 发送广播
44             Intent intent = new Intent("com.freshen.code.MyBroadcastReceiver2");
45             intent.putExtra("msg","广播信息 : 随机数 " + rand.nextInt(100));
46             // 发出广播
47             // 匹配 com.freshen.code.MyBroadcastReceiver 动作的广播接收器将接受到该广播
48             sendBroadcast(intent);
49             Log.i(TAG, "广播已发出");
50         }else if(arg0.getId() == R.id.bc_bt04){
51             // 解除广播接收器
52             if(receiver2 != null){
53                 unregisterReceiver(receiver2);    // 取消注册
54                 receiver2 = null;
55             }
56             Log.i(TAG, "执行解除注册操作");
57         }
58     }
59     
60     @Override
61     protected void onDestroy() {
62         super.onDestroy();
63         // 解除广播接收器
64         if(receiver2 != null)
65             unregisterReceiver(receiver2);    // 取消注册
66     }
67     
68 }
MainActivity.java

动态注册的广播无法驻留到系统,当应用程序的生命周期结束后,广播接收也随之消失。静态注册和动态注册在选择时应注意以下原则:

1、对于自己发送和接收的广播可以通过 registerReceive 动态注册,对于系统常用广播的接收通常用 <receiver> 标签注册。

2、registerReceive 可以手动控制,适当地注册和取消注册能节省系统资源,<receiver> 标签在系统开机后一直有效,动态注册能解决的问题尽量采用动态注册。

3、通过 registerReceive 注册的 BroadcastReceive 在对其进行注册的 Context 对象“销毁”了或者调用了 unregisterReceive 方法后广播也就失效了;而通过 <receiver> 标签注册的 BroadcastReceiver 只要应用程序没有被删除就一直有效。

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="fill_parent"
 4     android:layout_height="fill_parent"
 5     android:orientation="vertical" >
 6 
 7     <Button
 8         android:id="@+id/bc_bt01"
 9         android:layout_width="fill_parent"
10         android:layout_height="wrap_content"
11         android:text="发送广播,由静态注册接收器响应" />
12     <Button
13         android:id="@+id/bc_bt02"
14         android:layout_width="fill_parent"
15         android:layout_height="wrap_content"
16         android:text="动态注册广播" />
17     <Button
18         android:id="@+id/bc_bt03"
19         android:layout_width="fill_parent"
20         android:layout_height="wrap_content"
21         android:text="发送广播,由动态注册接收器响应" />
22     <Button
23         android:id="@+id/bc_bt04"
24         android:layout_width="fill_parent"
25         android:layout_height="wrap_content"
26         android:text="取消动态注册" />
27 
28 </LinearLayout>
main.xml

 

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