您的位置:首页 > 移动开发 > Android开发

Android 四大组件系列之---BroadcastReceiver 详解

2017-11-25 22:25 369 查看

1. BroadcastReceiver

广播 BroadcastReceiver 是 Android 四大组件之一,本质上就是一种全局的事件监听器,用于接收系统或者系统其他 App 发送的广播事件,因此可以很简单而又简洁的实现不同组件之间的通信。

使用场景:

同一App具有多个进程的不同组件之间的消息通信

不同App之间的组件之间的消息通信

2. 使用步骤

步骤:

继承 BroadcastReceiver 实现自己的广播接收器

只要重写BroadcastReceiver 的OnReceive(Context context, Intent intent)方法,用来处理自己的业务逻辑;

注册广播接收器,注册的方式有两种,静态注册和动态注册

静态注册:在AndroidManifest.xm文件中配置;

静态注册的广播接收器只要 app 在系统中运行则一直可以接收到广播消息.

动态注册:使用java代码注册,调用 BroadcastReceiver的 context 的registerReceiver(BroadcastReceiver receiver, IntentFilter filter);

动态注册的广播接收器当注册的 Activity 或者 Service 销毁了那么就接收不到广播了.

发送广播

根据发送方式的不同又不同的广播:

普通广播: endBroadcast(Intent intent) ;

有序广播: sendOrderedBroadcast(Intent intent) ;

本地广播(应用内广播):localBroadcastManager.sendBroadcast(intent);

3. 广播的分类

上面使用步骤中说了, 按照发送的方式可分为三种, 其实Android 系统广播细分的话有以下四种:

普通广播(Normal Broadcast)

发送出去后所有的广播接收器都会很快收到, 异步, 效率高。

缺点是一个接收器不能将处理后的结果传递给下一个接收器,并无法终止广播的传播。

有序广播(Ordered Broadcast)

在注册时可指定优先级,优先级高的广播接收者优先收到广播,优先级以一个整数来标识,取值范围是: -1000 ~ 1000, 数值越大优先级越高。可中断,前一个接收器收到后可添加新参数setResultExtras(Bundle)到intent中, 当广播传到下一个接收器时可将数据取出来getResultExtras(true)。

比如: 有三个广播接收者 A,B,C,优先级是 A > B > C。那这个消息先传给 A,再传给 B,最后传给 C。每个接收者有权终止广播,比如 B 终止广播,C 就无法接收到。此外 A 接收到广播后可以对结果对象进行操作,当广播传给 B 时,B 可以从结果对象中取得 A 存入的数据.

粘性广播(Sticky Broadcast)

发出的广播会滞留,注册时间可晚于发送时间,其他功能与无序广播相同。粘性广播在发送后就一直存在于系统的消息容器里面,等待对应的处理器去处理,如果暂时没有处理器处理这个广播则一直在消息容器里面处于等待状态,粘性广播的Receiver如果被销毁,那么下次重建时会自动接收到消息数据。

发送粘性广播需要权限

<uses-permission android:name="android.permission.BROADCAST_STICKY" />


本地广播(Local Broadcast)

本地广播是一种局部广播,广播的发送者和接收者都同属于一个App,相比于全局广播(普通广播),本地广播:效率更高, 安全性更高.

注册广播时将exported属性设置为false,非本应用内部发出的此广播不被接收;

4. 使用广播需要特别注意的地方:

1.广播接收器的生命周期非常短,在接收到广播的时候创建,onReceive()方法结束之后销毁;

2.广播接收器中不要做太耗时的工作,BroadcastReceiver 的 OnReceive()方法不能在10 s 内执行完成, Android 系统会认为该程序无响应, 弹出ANR(Application No Response) 错误对话框;

3.最好也不要在广播接收者中创建子线程做耗时的工作,因为广播接收者被销毁后进程就成为了空进程,很容易被系统杀掉

如果需要根据BroadcastReceiver来完成比较耗时的操作, 可以考虑通过Intent 启动一个service来完成耗时操作, 不能使用新线程去完成这个耗时操作, 因为BroadcastReceiver 的生命周期很短, 可能会出现子线程还没结束, BroadcastReceiver 就已经销毁了, 这时虽然如果新线程还没结束, 但由于该线程所在进程已经没有四大组件这样优先级高的组件,所以该新线程所在的进程随时都可能被销毁, 导致新线程里的耗时操作无法正常完成.

5. Android 7.0 广播新特性

在 Android 7.0 中,删除了三个常用隐式广播:

CONNECTIVITY_ACTION

ACTION_NEW_PICTURE

ACTION_NEW_VIDEO

删除这些广播可以显著提升设备性能和用户体验, 因为这些广播可能会一次唤醒多个应用的后台进程,同时会耗尽内存和电池。

为缓解这些问题,Android N 采取了以下优化措施:

1.在Android N平台下即使在 AndroidManifest.xml 清单文件中注册了 CONNECTIVITY_ACTION广播,在网络发生变化时也不会接收到任何的信息。但是正在前台运行的应用程序如果在主线程中通过Context.registerReceiver() 动态注册了CONNECTIVITY_ACTION广播,该应用程序仍然可以接收到该广播。

2.应用程序无法发送或接收 ACTION_NEW_PICTURE(拍照) 或 ACTION_NEW_VIDEO(录像) 广播。此项优化会影响所有应用,而不仅仅是面向 Android N 的应用。

如果您的应用使用任何上述广播,为了适配 Android N 设备请您尽快解除它们之间的依赖关系。 Android 框架提供多个解决方案来缓解对这些隐式广播的需求。比如,为了在特定的网络条件下执行特定的网络操作,Android提供了 JobScheduler 和 GcmNetworkManager。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: