1.5 清单文件中的receiver 广播接收器
2018-09-10 本文已影响17人
littlezan
清单文件中的 receiver 广播接收器
Android应用可以从Android系统和其他Android应用发送或接收广播消息,类似于 发布 - 订阅 设计模式。
应用可以注册以接收特定广播。当发送广播时,系统自动将广播路由到已订阅接收该特定类型广播的应用。
一般而言,广播可以用作跨应用程序和普通用户流程之外的消息传递系统。但是,不要滥用广播并在后台运行可能导致系统性能降低的工作
1. 实现原理
Android中的广播使用了设计模式中的观察者模式:基于消息的发布/订阅事件模型。因此,Android将广播的发送者和接收者极大程度解耦,使得系统能够方便集成,更易扩展。
具体流程如下:
- 自定义广播接收者BroadcastReceiver,并复写onRecvice()方法;
- 通过Binder机制向AMS(Activity Manager Service)进行注册;
- 广播发送者通过Binder机制向AMS发送广播;
- AMS查找符合相应条件(IntentFilter/Permission等)的BroadcastReceiver,将广播发送到BroadcastReceiver(一般情况下是Activity)相应的消息循环队列中;
- 消息循环执行拿到此广播,回调BroadcastReceiver中的onReceive()方法。
2. 注册广播的2种方式
在清单文件中注册
<receiver
//广播接收器是否可以直接启动,也就是说,它是否可以在用户解锁设备之前运行。默认值false
android:directBootAware = [“true” | “false” ]
//广播接收机是否可以由系统实例化
android:enabled=["true" | "false"]
//广播接收机是否可以从其应用程序之外的来源接收消息,如果false,则广播接收器可以接收的唯一消息是由相同应用程序的组件或具有相同用户ID的应用程序发送的消息。
默认值是由receiver中有无intent-filter决定的:如果有intent-filter,默认值为true,否则为false
android:exported=["true" | "false"]
android:icon="drawable resource"
android:label="string resource"
//继承BroadcastReceiver子类的类名
android:name=".mBroadcastReceiver"
//具有相应权限的广播发送者发送的广播才能被此BroadcastReceiver所接收;
android:permission="string"
//BroadcastReceiver运行所处的进程,默认为app的进程,可以指定独立的进程
android:process="string" >
//用于指定此广播接收器将接收的广播类型
//本示例中给出的是用于接收网络状态改变时发出的广播
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
示例:
<receiver
//此广播接收者类是MyBroadcastReceiver
android:name=".MyBroadcastReceiver" >
//用于接收网络状态改变时发出的广播
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
在代码中动态注册
在代码中通过调用Context的registerReceiver()方法进行动态注册BroadcastReceiver
@Override
protected void onResume() {
super.onResume();
//实例化BroadcastReceiver子类 & IntentFilter
MyBroadcastReceiver mBroadcastReceiver = new MyBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
//设置接收广播的类型
intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);
//调用Context的registerReceiver()方法进行动态注册
registerReceiver(mBroadcastReceiver, intentFilter);
}
取消订阅:
@Override
protected void onPause() {
super.onPause();
//销毁在onResume()方法中的广播
unregisterReceiver(mBroadcastReceiver);
}
对于动态广播,有注册就必然得有注销,否则会导致内存泄露。重复注册、重复注销也是不允许。
3. 广播的发送
广播的类型主要分5类
- 普通广播(Normal Broadcast)
- 系统广播(System Broadcast)
- 有序广播(Ordered Broadcast)
- App应用内广播(Local Broadcast)
- 粘性广播(Sticky Broadcast)
1. 普通广播(Normal Broadcast)
开发者自身定义intent的广播(最常用)。发送广播使用如下:
Intent intent = new Intent();
//对应BroadcastReceiver中intentFilter的action
intent.setAction(BROADCAST_ACTION);
//发送广播
sendBroadcast(intent);
注册广播:
<receiver
//此广播接收者类是mBroadcastReceiver
android:name=".mBroadcastReceiver" >
//用于接收网络状态改变时发出的广播
<intent-filter>
<action android:name="BROADCAST_ACTION" />
</intent-filter>
</receiver>
2. 系统广播(System Broadcast)
- Android中内置了多个系统广播:只要涉及到手机的基本操作(如开机、网络状态变化、拍照等等),都会发出相应的广播
- 每个广播都有特定的Intent - Filter(包括具体的action)
3. 有序广播(Ordered Broadcast)
- 发送出去的广播被广播接收者按照先后顺序接收
- 广播接受者接收广播的顺序按照Priority属性值从大-小排序;Priority属性相同者,动态注册的广播优先;
sendOrderedBroadcast(intent);
4. App应用内广播(Local Broadcast)
App应用内广播可理解为一种局部广播,广播的发送者和接收者都同属于一个App。
主要使用系统提供LocalBroadcastManager来发送,注册广播。
注册本地广播接收器:
mBroadcastReceiver = new mBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
//步骤2:实例化LocalBroadcastManager的实例
localBroadcastManager = LocalBroadcastManager.getInstance(this);
//步骤3:设置接收广播的类型
intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);
//步骤4:调用LocalBroadcastManager单一实例的registerReceiver()方法进行动态注册
localBroadcastManager.registerReceiver(mBroadcastReceiver, intentFilter);
取消注册
//取消注册应用内广播接收器
localBroadcastManager.unregisterReceiver(mBroadcastReceiver);
发送本地广播:
//发送应用内广播
Intent intent = new Intent();
intent.setAction(BROADCAST_ACTION);
localBroadcastManager.sendBroadcast(intent);
5. 粘性广播(Sticky Broadcast)
由于在Android5.0 & API 21中已经失效,