Android 四大组件——广播接收器 详解

来源:互联网 发布:软件测试技术考题 编辑:程序博客网 时间:2024/05/22 13:14

转载请注明出处:http://blog.csdn.net/smartbetter/article/details/51488281

记得小时候上学的时候,每个班级门口都会安装一个喇叭,这些喇叭都是接入到学校的广播室的,一旦有什么通知,就会播放来告知全校的师生。类似的工作机制其实在计算机领域也有着广泛的应用。为了方便进行系统级别的消息通知,Android引入了一套类似的广播消息机制。Android提供了一套完整的API,允许应用程序自由地发送和接收广播,发送广播是通过Intent发送的,而接受广播则需要引入广播接受器BroadcastReceiver。BroadcastReceiver用于监听系统全局的广播消息,接受程序所发出的Broadcast Intent。

1.广播机制简介

Android中广播主要分为两种类型:

Broadcast(广播) 特点 Normal Broadcast(标准广播) 完全异步执行,效率高,无法被截断。 Ordered Broadcast(有序广播) 同步执行,广播接受器有先后顺序,优先级高的广播接受器先接受,并且可截断。

Broadcast

2.接受系统广播

Android内置了很多系统级别的广播,比如手机开机后会发出一条广播,电池电量发生变化会发出一条广播,时间或时区发生变化也会发出一条广播,等等。我们可以通过监听这些广播得到系统的状态信息。下面提供一些常见的Action常量:

Action常量 对应字符串 简单说明 ACTION_TIME_CHANGED android.intent.action.TIME_SET 系统时间被改变 ACTION_DATE_CHANGED android.intent.action.DATE_CHANGED 系统日期被改变 ACTION_BOOT_COMPLETED android.intent.action.BOOT_COMPLETED 系统启动完成 ACTION_SHUTDOWN android.intent.action.ACTION_SHUTDOWN 系统被关闭 ACTION_BATTERY_LOW android.intent.action.BATTERY_LOW 电池电量低 ACTION_POWER_CONNECTED android.intent.action.ACTION_POWER_CONNECTED 系统连接电源 ACTION_POWER_DISCONNECTED android.intent.action.ACTION_POWER_DISCONNECTED 系统与电源断开 CONNECTIVITY_CHANGE_ACTION android.net.conn.CONNECTIVITY_CHANGE 网络变化

1.动态注册广播(在代码中注册)

在代码中注册广播,只需要新建一个类,继承自BroadcastReceiver,并重写父类onReceive()方法就行了。

private IntentFilter intentFilter;private MyReceiver receiver;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    intentFilter = new IntentFilter();    intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");    receiver = new MyReceiver();    registerReceiver(receiver, intentFilter);}@Overrideprotected void onDestroy() {    super.onDestroy();    unregisterReceiver(receiver);}class MyReceiver extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        Log.i("JAVA", "network changes");    }}

需要注意的是,动态注册的广播接受器一定都要取消注册才行,这里我们是在onDestroy()方法中通过调用unregisterReceiver()方法来实现的。

2.静态注册广播(在AndroidManifest.xml中注册)

动态注册广播有一个缺点就是必须要程序启动后才能接受广播,而静态注册广播可以让程序在未启动的情况下就能接受到广播。

我们新建一个广播接收器:

public class MyReceiver extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        Log.i("JAVA","power changes");    }}

然后在 AndroidManifest.xml 文件中 与 activity 同级下 注册 BroadcastReceiver 即可:

<receiver    android:name=".MyReceiver"    android:enabled="true"    android:exported="true">    <intent-filter>        <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>    </intent-filter></receiver>

需要注意的是,不要在 onReceive() 方法中添加过多的逻辑或者进行任何的耗时操作,因为在广播接收器中是不允许开启线程的,当 onReceive() 方法运行了较长时间而没有结束时,程序就会报错。

3.发送自定义广播

前面已经介绍过了,广播主要分为两种类型:标准广播和有序广播,下面我们就看一下这两种广播具体的区别:

1.发送标准广播

在发送广播之前,我们先定义一个广播接收器来准备接受此广播才行:

public class MyReceiver extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        Log.i("JAVA","received in MyReceiver");    }}

然后在 AndroidManifest.xml 文件中对这个广播接收器进行修改:

<receiver    android:name=".MyReceiver"    android:enabled="true"    android:exported="true">    <intent-filter>        <action android:name="com.demo.broadcasttest.MY_BROADCAST"/>    </intent-filter></receiver>

最后在 MainActivity 中添加下面代码作为发送广播的触发点:

Intent intent = new Intent("com.demo.broadcasttest.MY_BROADCAST");sendBroadcast(intent);     // 发送Normal Broadcast

另外,由于广播是使用 Intent 进行传递的,因此还可以在 Intent 中携带一些数据传递给广播接收器。

2.发送有序广播

广播说一种跨进程的通信方式。

发送有序广播也是比较简单的,对比标准广播,有序广播只需要改动一行代码,即将 sendBroadcast() 方法 改成 sendOrderedBroadcastt() 方法:

Intent intent = new Intent("com.demo.broadcasttest.MY_BROADCAST");sendOrderedBroadcast(intent, null);     // 发送Ordered Broadcast

下一步我们在 AndroidManifest.xml 文件中 设定广播的先后顺序:

<receiver    android:name=".MyReceiver"    android:enabled="true"    android:exported="true">    <intent-filter android:priority="100">        <action android:name="com.demo.broadcasttest.MY_BROADCAST"/>    </intent-filter></receiver>

可以看到,通过 android:priority 属性给广播接受器设置了优先级,优先级比较高的广播接收器就可以先收到广播。
既然已经获取了接受广播的优先权,那么MyReceiver就可以选择是否允许广播接收器继续传递了,修改MyReceiver的代码:

public class MyReceiver extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        Log.i("JAVA","received in MyReceiver");        abortBroadcast();   // 表示广播被截断    }}

4.使用本地广播

前面我们发送和接收的广播全部属于系统全局广播,发出的广播可以被其他任何程序接受到,容易引发安全性的问题,为了能够简单地解决广播的安全性问题,Android引入了一套本地广播机制,使用这个机制发出的广播只能够在应用程序的内部进行传递,并且广播接收器也只能接受来自本地应用程序发出的广播,这样所有的安全性问题就都不存在了。

本地广播主要就是使用了一个 LocalBroadcastManager 来对广播进行管理,并提供了发送广播和注册广播接收器的方法。

private IntentFilter intentFilter;private LocalReceiver localReceiver;private LocalBroadcastManager localBroadcastManager;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    localBroadcastManager = LocalBroadcastManager.getInstance(this); // 获取实例    Intent intent = new Intent("com.demo.broadcasttest.LOCAL_BROADCAST");    localBroadcastManager.sendBroadcast(intent);  // 发送本地广播    intentFilter = new IntentFilter();    intentFilter.addAction("com.demo.broadcasttest.LOCAL_BROADCAST");    localReceiver = new LocalReceiver();    localBroadcastManager.registerReceiver(localReceiver, intentFilter);  // 注册本地广播监听器}@Overrideprotected void onDestroy() {    super.onDestroy();    localBroadcastManager.unregisterReceiver(localReceiver);}class LocalReceiver extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        Log.i("JAVA","received local broadcast");        abortBroadcast();    }}

另外还有一点需要说明,本地广播是无法通过静态注册的方式来接受的。

17 0
原创粉丝点击