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. centos6安装pxc

    Percona XtraDB Cluster是一种高可用性解决方案,可帮助企业避免停机和中断. Percona XtraDB Cluster具有以下MySQL群集优势: • 具有成本效益的HA和MyS ...

  2. Server MyEclipse Tomcat v7.0 was unable to start within 45 seconds. If the server requires more time

    启动Tomcat服务器时经常遇到这个错误, Server MyEclipse Tomcat v7.0 was unable to start within 45 seconds. If the ser ...

  3. MySQL必知必会(通配符过滤Like,%,_)

    SELECT prod_id, prod_name FROM products WHERE prod_name LIKE 'jet%'; #百分号(%)表示任何字符出现任意次数, %不能匹配值为NUL ...

  4. luogu P4462 [CQOI2018]异或序列 |莫队

    题目描述 已知一个长度为n的整数数列a1,a2,...,an,给定查询参数l.r,问在al,al+1,...,ar​区间内,有多少子序列满足异或和等于k.也就是说,对于所有的x,y (I ≤ x ≤ ...

  5. Spring AOP简介与底层实现机制——动态代理

    AOP简介 AOP (Aspect Oriented Programing) 称为:面向切面编程,它是一种编程思想.AOP 是 OOP(面向对象编程 Object Oriented Programmi ...

  6. react-native 相对项目路径导入组件 ___ babel-plugin-module-resolver

    babel-plugin-module-resolver 是一个Babel模块解析插件, 在.babelrc中可以配置模块的导入搜索路径. 为模块添加一个新的解析器.这个插件允许你添加新的" ...

  7. 大数据之Linux基本指令

    1:文件操作类指令 ls 是英文单词list 的简写, 其功能为列出目录的内容,是最常用的命令之一 -a all 显示指定目录下所有子目录与文件, 包含隐藏文件 -l 以列表方式显示文件的详细信息 - ...

  8. [TimLinux] Python 使用入门

    1. 为什么用Python 软件质量:Python注重可读性.一致性和软件质量. 提高开发者的效率:Python代码的大小往只有C++/Java代码的1/5 ~ 1/3. 程序的可移植性:绝大多数Py ...

  9. acm博弈论基础总结

    acm博弈论基础总结 常见博弈结论 Nim 问题:共有N堆石子,编号1..n,第i堆中有个a[i]个石子. 每一次操作Alice和Bob可以从任意一堆石子中取出任意数量的石子,至少取一颗,至多取出这一 ...

  10. 赌十包辣条,你一定没见过这么通透的ThreadLocal讲解

    1.看个热闹 鉴于普罗大众都喜欢看热闹,咱们先来看个热闹再开工吧! 场景一: 中午了, 张三.李四和王五一起去食堂大菜吃饭.食堂刚经营不久,还很简陋,负责打菜的只有一位老阿姨. 张三:我要一份鸡腿. ...