对于广播,大家都比较熟悉了,本篇只是作为学习总结,也希望可以帮到他人,如有错误,希望大家指正,大家共同学习进步,道宜光大,术切私藏。
广播机制简介
在Android中,有一些操作完成以后,就会发送广播,比如说发出一条短信,或着打出一个电话,如果某个程序接收了这个广播,就会做相应的处理,也可以不处理。广播也可以被不止一个程序接收,当然也可能不被其他任何应用程序所接收。
广播机制最大的特点就是发送方并不关心接收方是否接到数据,也不关心接收方是如何处理数据的。
广播机制三要素
Android广播机制包含三个基本要素:
广播(Broadcast) - 用于发送广播;
广播接收器(BroadcastReceiver) - 用于接收广播;
意图内容(Intent)-用于保存广播相关信息的媒介。
广播的生命周期
一个广播接收者都有一个回调方法: void onReceive(Context context, Intent intent) , 当一条广播 被广播接收器接收时,Android调用它的onReceive()方法并传递给它包含消息的Intent对象。广播接收者被认为仅当它执行这个方法时是活跃的。当onReceive()返回后,它是不活跃的。
广播分类
android中的广播,按有无顺序区分,可以分为:标准广播、有序广播。
- 1 标准广播。就是在广播发出以后 ,所有的广播接收者,几乎同时接收到这条广播,发出的广播是完全异步的,广播接收者收到广播没有先后顺序。按理想状况来说,广播接收者是同一时间接收到系统发出的广播。特点就是 效率高,无法截断。
- 2 有序广播。就是在广播发出以后 ,同一时刻,只有一个广播接收者能够接收这条广播,当这个广播接收器中的逻辑处理完毕以后,广播才会向下继续传递,此时的广播接收器有先后顺序。优先级高的先接收,优先级高的广播接收者,还可以控制是否将广播往下继续传递;特点就是,相对标准广播效率低些,可以截断
实现流程
具体实现流程要点粗略概括如下: 注册 –发送–接收–获取
- 广播接收者BroadcastReceiver通过Binder机制向AMS(Activity Manager Service)进行注册;
- 广播发送者通过binder机制向AMS发送广播;
- AMS查找符合相应条件(IntentFilter/Permission等)的BroadcastReceiver,将广播发送到BroadcastReceiver(一般情况下是Activity)相应的消息循环队列中;
- 消息循环执行拿到此广播,回调BroadcastReceiver中的onReceive()方法。
广播的注册
根据注册方式不同有静态注册、动态注册。
- 1 静态注册 AndroidManifest + java 类
静态注册方式的特点:不管该应用程序是否处于活动状态,都会进行监听。
几个属性 说明一下 - android:exported ——此broadcastReceiver能否接收其他App的发出的广播,其默认值是由receiver中有无intent-filter决定的,如果有intent-filter,默认值为true,否则为false。(同样的,activity/service中的此属性默认值一样遵循此规则)同时,需要注意的是,这个值的设定是以application或者application user id为界的,而非进程为界(一个应用中可能含有多个进程);
- android:permission ——如果设置,具有相应权限的广播发送方发送的广播才能被此broadcastReceiver所接收;
- android:process ——broadcastReceiver运行所处的进程。默认为app的进程。可以指定独立的进程(Android四大基本组件都可以通过此属性指定自己的独立进程)
- priority: 广播优先级
- name:广播name,唯一标示。
- 2 动态注册
动态注册方式在activity里面调用函数来注册,
特点:在代码中进行注册后,当应用程序关闭后,就不再进行监听。
广播的发送
- 1 发送标准广播
sendBroadcast(Intent); - 2.1发送有序广播
sendOrderedBroadcast(Intent,null)
2.2 截断广播,后面的广播接收器就无法接收那条广播
aborBoadcast(); - 3 发送本地广播
本地广播的特点:
- 1 本地广播只能在本App中传播,并且广播接收器也只能接收来自本APP发出的广播,所以在该情况下可防止其他应用获取广播中的敏感数据从而确保数据安全.
- 2 本地广播只能使用在代码中动态注册的方式.
private IntentFilter mIntentFilter;
private LocalBroadcastManager mLocalBroadcastManager;
private LocalBroadcastReceiver mLocalBroadcastReceiver;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
registerLocalBroadcastReceiver()
}
/**
* 注册本地广播接收者
*/
private void registerLocalBroadcastReceiver(){
//注册应用内广播接收器
localBroadcastManager = LocalBroadcastManager.getInstance(this);
localBroadcastManager.registerReceiver(mLocalBroadcastReceiver, intentFilter);
}
/**
* 取消本地广播的注册
*/
private void unRegisterLocalBroadcastReceiver(){
if (mLocalBroadcastManager!=null) {
if (mLocalBroadcastReceiver!=null) {
mLocalBroadcastManager.unregisterReceiver(mLocalBroadcastReceiver);
}
}
}
补充
onReceive方法中不能执行太耗时的操作。否则将产生ANR。一般情况下,广播接收器的业务 更多的是打开其他程序组件 的作用,如发送Notification、启动service等。
注册广播一般会牵连到一些权限问题,so 有些权限要声明。
动态注册广播(有序广播和本地广播),广播接受者需要在Destory回调事件进行 void unregisterReceiver(BroadCastReceiver)。
笔者水平有限,若有错漏,欢迎指正 ,谢谢