Android组件体系之BroadcastReceiver小结
1、常见分类
BroadCastReceiver,按注册方式可以分为静态广播接收器和动态广播接收器。
静态广播接收器:不受程序是否启动的约束,当应用程序关闭之后,还是可以接收到广播(一般广播接收器的生命周期是和当前活动的生命周期保持同步)。
动态广播接收器:可以自由的控制注册和取消,有很大的灵活性。但是只能在程序启动之后才能收到广播。
对于广播(Broadcast),则可以分为普通广播和有序广播。
其中普通广播不在意顺序,各进程的广播接收器基本上可以同时收到这个广播。而有序广播,系统会根据接收者声明的优先级按顺序逐个接收处理,先收到有序广播的接收器,可以对该有序广播进行修改或者截断。
静态注册的广播接收器,在接收广播时,系统自动按有序广播的方式来串行处理(原因是进程的创建不能并发),此类接收器收到广播的先后顺序,和接收器所在package名称有关,或者说,和PMS扫描顺序有关。
动态注册的广播接收器,如果接收普通广播,接收器收到广播的顺序则和注册顺序有关。在所有普通广播里面,动态注册的广播接收器,相对于静态注册的广播接收器,会优先收到普通广播。
同优先级的动态有序广播,注册顺序影响广播的接收顺序;同优先级的静态有序广播,扫描顺序影响其接收顺序。
除了前面提到的这些,还有一种相对不太常用的:LocalBroadcastManager方式注册的应用内广播接收器,只能通过LocalBroadcastManager动态注册。
2、注册过程简述
动态注册的广播接收器,主要通过ContextImpl、LoadedApk,再调用AMS的registerReceiver方法完成。
静态注册的广播接收器,是在系统启动时,由PMS解析apk文件并记录receivers信息,然后AMS调用PMS的接口来查询intent匹配信息,再完成广播注册过程。
3、发送和接收过程简述
发送广播,主要通过ContextImpl、LoadedApk、AMS、ActivityThread完成。接收广播时,先是在AMS里面处理,找到接收者然后加到一个队列,再向对应的线程发送广播消息。
从Android O开始,系统对静态注册的广播接收器添加了限制,必须指定广播接收器所在包名才可以发送,或者使用Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND这个flag,但该标志是隐藏的,如果必须使用静态广播接收器、又不能指定包名(例如发送一对多的广播),则可以使用该标志的具体数值0x01000000。
4、安全性
可以使用权限提升广播接收的安全性。如果接收器定义了权限,发送的广播需要对应声明权限才能发送;反之一样,不然收不到。整体上,有以下几种情况:
- 指定发送方,发送者有权限才能发此广播;
- 指定接收方,接收者声明权限才能收到该广播;
- 同时指定发送方和接收方(很少使用)。
无论是哪种情况,都涉及到自定义权限,所以都需要在AndroidManifest.xml中声明对应的权限。
对于第一种情况(接收器定义权限来限制发送方),如果是动态广播接收器,可以在注册时通过registerReceiver传入该权限。静态广播接收器则是在AndroidManifest.xml里面,定义广播接收器的地方,添加android:permission属性,将该属性设为自定义权限。
5、 onReceive()中的Context入参
这里的入参为context变量,其实例的具体类型,可以分为下面几种情况。
1)、静态注册的广播接收器
这种情况下,入参是android.app.ReceiverRestrictedContext类型,不能用来启动Activity、弹出AlertDialog(除了系统应用且Dialog类型是SYSTEM_ALERT_WINDOW类型)。
2)、动态注册的广播接收器
具体又分两种情况:
a) 在Activity里面注册广播接收器。此时onReceive的入参context就是注册广播接收器的Activty对象。
由于此时入参contex为Activity的Context对象,可用于启动Activity、弹出AlertDialog。
但考虑到onReceive()方法在主线程中,该方法需要在10秒内执行完毕,生命周期很短。如果弹出的对话框需要等待用户响应,就需要考虑对话框的管理问题。常用的做法是,将其放在Service里面管理,在Service启动的时候注册一个动态广播接收器,Service停止的时候注销之。
b) 在Service里面注册广播接收器。此时onReceive的入参context对应该Service对象,和Service是否跨进程无关。这种情况下的Context不能启动Activity,有若干限制。
这两种情况可以统一为,onReceive的入参context就是调用registerReceiver的组件的Context。
其他还有LocalBroadcastManager注册的应用内广播接收器。其onReceive中的context是Application的Context。
(相关完整且成体系的文章,可参见本人原创的开源电子书《Android系统与性能优化》,地址:https://github.com/carylake/androidnotes)
Android组件体系之BroadcastReceiver小结的更多相关文章
- Android组件体系之视图绘制
一.View组件View组件有几个重要的方法需要关注,也是自定义View经常需要重写的方法. 1.measure作用是测量View组件的尺寸.对应的方法是onMeasure,测量View的宽和高.Vi ...
- Android组件体系之ContentProvider使用注意事项
1.数据访问机制 客户端/调用者通过getContentResolver调用,由ActivityThread.AMS获取到ContentProvider的代理,再通过这个代理对象调用服务端的实现(也即 ...
- Android组件体系之Service解析
一.调用方式 1.启动服务 只启动一个服务,不进行通信,包括startService.startForegroundService两种调用方式.第二种方式适用于后台应用启动前台服务,在启动 ...
- Android组件体系之Activity启动模式解析
本文主要分析Activity的启动模式及使用场景. 一.Activity启动模式浅析 1.standard 标准模式,系统默认的启动模式.在启动Activity时,系统总是创建一个新的Activity ...
- Android组件系列----BroadcastReceiver广播接收器
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...
- Android 四大组件学习之BroadcastReceiver一
本节课学习四大组件最后一个, 广播接受者. 顾名思义广播接受者就是接受广播呗.比方在现实社会中,曾经每一个人家都有一台收音机,这可就能够去接受广播发出来的消息.大家都知道.程序世界也是參照的显示生活设 ...
- Android 四大组件学习之BroadcastReceiver二
上节学习了怎样创建一个广播.也尝试接受系统打电话的广播. 本节课学习怎样自己定义广播.自己定义广播实质上也就是创建一个发送广播者,创建一个接受该广播者. 那我们就開始行动吧. 先创建一个发送广播的应用 ...
- 【Android开发精要笔记】Android组件模型解析
Android组件模型解析 Android中的Mashup 将应用切分成不同类别的组件,通过统一的定位模型和接口标准将他们整合在一起,来共同完成某项任务.在Android的Mashup模式下,每个组件 ...
- 使用Broadcast实现android组件之间的通信 分类: android 学习笔记 2015-07-09 14:16 110人阅读 评论(0) 收藏
android组件之间的通信有多种实现方式,Broadcast就是其中一种.在activity和fragment之间的通信,broadcast用的更多本文以一个activity为例. 效果如图: 布局 ...
随机推荐
- python基础-网络编程part02
TCP协议 TCP是传输控制协议,建立双向通道. 三次握手,建立连接 客户端向服务端发送建立连接的请求 服务端接收请求返回确认信息给客户端,并向客户端发送建立连接的请求 客户端接收请求返回确认信息给服 ...
- 1、Docker 简介
目录 Docker 起源 Docker 架构 特性 局限 名称空间隔离 原理 Control Groups (cgroups) Docker Docker 啥是docker? Docker 是一个开源 ...
- 原生js删除增加修改class属性
其实html5已经扩展了class操作的相关API,其中classList属性就以及实现了class的增删和判断. HTML DOM classList 属性 classList属性的方法有: add ...
- SpringSecurity框架下实现CSRF跨站攻击防御
一.什么是CSRF 很多朋友在学习Spring Security的时候,会将CORS(跨站资源共享)和CSRF(跨站请求伪造)弄混,以为二者是一回事.其实不是,先解释一下: CORS(跨站资源共享)是 ...
- Sql like模糊查询 区分大小写
Sql模糊查询,Like默认是不区分大小写的 使用Like时,怎么支持大小写呢? upper.lower,只能模糊所有的内容,不能区分内容中的大小写. sqlite数据库对text字段默认是大小写敏感 ...
- 大型情感剧集Selenium:4_老中医教你(单/多/下拉框)选项定位 #华为云·寻找黑马程序员#
今天讲什么 讲什么标题说了,讲selenium的单选.多选.下拉框选项定位.但其实这东西,没什么太多说的,又比较枯燥,那该怎么让这一集selenium的课程变得有趣呢?有请老中医,哈哈- 怎么样,这个 ...
- 一条数据的HBase之旅,简明HBase入门教程4:集群角色
[摘要] 本文主要介绍HBase与HDFS的关系,一些关键进程角色,以及在部署上的建议 HBase与HDFS 我们都知道HBase的数据是存储于HDFS里面的,相信大家也都有这么的认知: HBase是 ...
- 关于简单的Excel多页签底层导出_电子底账导出为例(.net core)
[HttpPost] public ActionResult ExpEleAcc(string linknos) { string filenname = null; CommonResult< ...
- Unity3D for iOS初级教程:Part 3/3(下)
转自:http://www.cnblogs.com/alongu3d/archive/2013/06/01/3111739.html 消息不会自动消除 你基本的游戏功能已经完成了,但是显示一些关于游戏 ...
- React中autoComplete="off" 失效
Turning Off Autocomplete in Chrome with React tl;dr Add a hidden input with an arbitrary value attri ...