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小结的更多相关文章

  1. Android组件体系之视图绘制

    一.View组件View组件有几个重要的方法需要关注,也是自定义View经常需要重写的方法. 1.measure作用是测量View组件的尺寸.对应的方法是onMeasure,测量View的宽和高.Vi ...

  2. Android组件体系之ContentProvider使用注意事项

    1.数据访问机制 客户端/调用者通过getContentResolver调用,由ActivityThread.AMS获取到ContentProvider的代理,再通过这个代理对象调用服务端的实现(也即 ...

  3. Android组件体系之Service解析

    一.调用方式    1.启动服务    只启动一个服务,不进行通信,包括startService.startForegroundService两种调用方式.第二种方式适用于后台应用启动前台服务,在启动 ...

  4. Android组件体系之Activity启动模式解析

    本文主要分析Activity的启动模式及使用场景. 一.Activity启动模式浅析 1.standard 标准模式,系统默认的启动模式.在启动Activity时,系统总是创建一个新的Activity ...

  5. Android组件系列----BroadcastReceiver广播接收器

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...

  6. Android 四大组件学习之BroadcastReceiver一

    本节课学习四大组件最后一个, 广播接受者. 顾名思义广播接受者就是接受广播呗.比方在现实社会中,曾经每一个人家都有一台收音机,这可就能够去接受广播发出来的消息.大家都知道.程序世界也是參照的显示生活设 ...

  7. Android 四大组件学习之BroadcastReceiver二

    上节学习了怎样创建一个广播.也尝试接受系统打电话的广播. 本节课学习怎样自己定义广播.自己定义广播实质上也就是创建一个发送广播者,创建一个接受该广播者. 那我们就開始行动吧. 先创建一个发送广播的应用 ...

  8. 【Android开发精要笔记】Android组件模型解析

    Android组件模型解析 Android中的Mashup 将应用切分成不同类别的组件,通过统一的定位模型和接口标准将他们整合在一起,来共同完成某项任务.在Android的Mashup模式下,每个组件 ...

  9. 使用Broadcast实现android组件之间的通信 分类: android 学习笔记 2015-07-09 14:16 110人阅读 评论(0) 收藏

    android组件之间的通信有多种实现方式,Broadcast就是其中一种.在activity和fragment之间的通信,broadcast用的更多本文以一个activity为例. 效果如图: 布局 ...

随机推荐

  1. python基础-网络编程part02

    TCP协议 TCP是传输控制协议,建立双向通道. 三次握手,建立连接 客户端向服务端发送建立连接的请求 服务端接收请求返回确认信息给客户端,并向客户端发送建立连接的请求 客户端接收请求返回确认信息给服 ...

  2. 1、Docker 简介

    目录 Docker 起源 Docker 架构 特性 局限 名称空间隔离 原理 Control Groups (cgroups) Docker Docker 啥是docker? Docker 是一个开源 ...

  3. 原生js删除增加修改class属性

    其实html5已经扩展了class操作的相关API,其中classList属性就以及实现了class的增删和判断. HTML DOM classList 属性 classList属性的方法有: add ...

  4. SpringSecurity框架下实现CSRF跨站攻击防御

    一.什么是CSRF 很多朋友在学习Spring Security的时候,会将CORS(跨站资源共享)和CSRF(跨站请求伪造)弄混,以为二者是一回事.其实不是,先解释一下: CORS(跨站资源共享)是 ...

  5. Sql like模糊查询 区分大小写

    Sql模糊查询,Like默认是不区分大小写的 使用Like时,怎么支持大小写呢? upper.lower,只能模糊所有的内容,不能区分内容中的大小写. sqlite数据库对text字段默认是大小写敏感 ...

  6. 大型情感剧集Selenium:4_老中医教你(单/多/下拉框)选项定位 #华为云·寻找黑马程序员#

    今天讲什么 讲什么标题说了,讲selenium的单选.多选.下拉框选项定位.但其实这东西,没什么太多说的,又比较枯燥,那该怎么让这一集selenium的课程变得有趣呢?有请老中医,哈哈- 怎么样,这个 ...

  7. 一条数据的HBase之旅,简明HBase入门教程4:集群角色

    [摘要] 本文主要介绍HBase与HDFS的关系,一些关键进程角色,以及在部署上的建议 HBase与HDFS 我们都知道HBase的数据是存储于HDFS里面的,相信大家也都有这么的认知: HBase是 ...

  8. 关于简单的Excel多页签底层导出_电子底账导出为例(.net core)

    [HttpPost] public ActionResult ExpEleAcc(string linknos) { string filenname = null; CommonResult< ...

  9. Unity3D for iOS初级教程:Part 3/3(下)

    转自:http://www.cnblogs.com/alongu3d/archive/2013/06/01/3111739.html 消息不会自动消除 你基本的游戏功能已经完成了,但是显示一些关于游戏 ...

  10. React中autoComplete="off" 失效

    Turning Off Autocomplete in Chrome with React tl;dr Add a hidden input with an arbitrary value attri ...