BroadcastReceiver的总结

来源:互联网 发布:淘宝csgo国际服 编辑:程序博客网 时间:2024/06/03 19:30

一.概述

BroadcastReceiver作为四大组件之一,对发送出来的 Broadcast 进行过滤、接收和响应。
BroadcastReceiver没有实现图形用户界面,但是当它收到消息后,可以启动Activity,Service或者通过NotificationMananger提醒用户等等作为响应。

二.应用场景

1.不同组件之间通信(包括应用内 / 不同应用之间)。
2. 与 Android 系统在特定情况下的通信(比如当电话呼入时、网络可用时)。
3. 多线程通信。

三.BroadcastReceiver的分类

类别 定义 特点 注意 普通广播(Normal Broadcast) 发送一个广播,所有监听该广播的广播接收者都可以监听到该广播。 发送一个广播,所有监听该广播的广播接收者都可以监听到该广播。 如果发送广播有相应权限,那么广播接收者也需要相应权限 系统广播(System Broadcast) Android中内置了多个系统广播:只要涉及到手机的基本操作(如开机、网络状态变化、拍照等等),都会发出相应的广播 当使用系统广播时,只需要在注册广播接收者时定义相关的action即可,并不需要手动发送广播,当系统有相关操作时会自动进行系统广播 Android7.0以上应用不会接受和发送以下三种广播CONNECTIVITY_ACTION广播(网络状态改变);ACTION_NEW_PICTURE广播(一个新的相机,拍照和图片的添加);ACTION_NEW_VIDEO广播(一个新的视频摄像记录下来)->解决方案使用使用JobScheduler API 有序广播(Ordered Broadcast) 发送出去的广播被广播接收者按照先后顺序接收 先接收的广播接收者可以对广播进行截断,即后接收的广播接收者不再接收到此广播;先接收的广播接收者可以对广播进行修改,那么后接收的广播接收者将接收到被修改后的广播 广播顺序:按照Priority属性值(-1000到1000之间,值越大,优先级越高)从大到小排序,Priority属性相同者,动态注册的广播优先 App应用内广播(Local Broadcast) App应用内广播可理解为一种局部广播,广播的发送者和接收者都同属于一个App。 相比于全局广播(普通广播),App应用内广播优势体现在安全性高和效率高

四.BroadcastReceiver的使用

BroadReceiver的使用可以分为三步:注册Receiver,发送广播,接收Receiver。
BroadcastReceiver的两种注册方式:

注册方式 定义 特点 静态注册 在清单文件中为 BroadcastReceiver 进行注册 a:不管该应用程序是否处于活动状态,都会进行监听,无需担忧广播接收器是否被关闭。b:会耗电,占内存。 动态注册 在程序中使用Context.registerReceiver注册 a:在代码中进行注册后,当应用程序关闭后,就不再进行监听。b:在 Android 的广播机制中,动态注册的优先级是要高于静态注册优先级的。

1.静态注册:
在清单文件中为 BroadcastReceiver 进行注册,使用< receiver >标签声明,并在标签内用 < intent-filter > 标签设置过滤器。
普通广播:
(1)新建StaticReceiver.java,继承BroadcastReceiver,并实现onReceiver方法。

public class StaticReceiver extends BroadcastReceiver{    private static final String TAG = "StaticReceiver";    @Override    public void onReceive(Context context, Intent intent) {        Log.d(TAG, "onReceive: ");//收到消息进行处理        Intent intent1 = new Intent(context, SendActivity.class);        context.startActivity(intent1);    }}

(2)清单文件中注册StaticReceiver:

<receiver android:name=".StaticReceiver">            <intent-filter>                <action android:name="com.liuwei.staticReceiver"/>            </intent-filter>        </receiver>

(3)使用sendBroadcast方法发送广播:

Intent intent = new Intent();                intent.setAction("com.liuwei.staticReceiver");sendBroadcast(intent);

其中在清单文件中设置android:priority属性可以设置优先级,值越大,优先级越高,可以发送有序广播。

<receiver android:name=".StaticReceiver">            <intent-filter android:priority="98">                <action android:name="com.liuwei.staticReceiver"/>            </intent-filter>        </receiver>

有序广播:
(1)新建StaticReceiver1.java,StaticReceiver2.java,StaticReceiver3.java三个类,继承BroadcastReceiver并实现onReceiver方法。

<receiver android:name=".StaticReceiver1">            <intent-filter android:priority="99">                <action android:name="com.liuwei.staticOrderReceiver"/>            </intent-filter>        </receiver>        <receiver android:name=".StaticReceiver2">            <intent-filter android:priority="22">                <action android:name="com.liuwei.staticOrderReceiver"/>            </intent-filter>        </receiver>        <receiver android:name=".StaticReceiver3">            <intent-filter android:priority="66">                <action android:name="com.liuwei.staticOrderReceiver"/>            </intent-filter>        </receiver>

其中清单文件中设置android:priority表示优先级,值越大,优先级越高。

Intent intent = new Intent();                intent.setAction("com.liuwei.staticOrderReceiver");sendOrderedBroadcast(intent, null);

(2)使用sendOrderedBroadcast(Intent intent,String receiverPermission);方法发送有序广播。
关于sendOrderedBroadcast方法中receiverPermission参数自定义权限的说明:
在清单文件中添加一个 < permission > 标签来声明自定义权限。

<permission        android:name="com.example.permission.receiver"        android:protectionLevel="signature" />
属性值 说明 normal 默认值。较低风险的权限,对其他应用,系统和用户来说风险最小。系统在安装应用时会自动批准授予应用该类型的权限,不要求用户明确批准(虽然用户在安装之前总是可以选择查看这些权限) dangerous 较高风险的权限,请求该类型权限的应用程序会访问用户私有数据或对设备进行控制,从而可能对用户造成负面影响。因为这种类型的许可引入了潜在风险,所以系统可能不会自动将其授予请求的应用。例如,系统可以向用户显示由应用请求的任何危险许可,并且在继续之前需要确认,或者可以采取一些其他方法来避免用户自动允许。 signature 只有在请求该权限的应用与声明权限的应用使用相同的证书签名时,系统才会授予权限。如果证书匹配,系统会自动授予权限而不通知用户或要求用户的明确批准 signatureOrSystem 系统仅授予Android系统映像中与声明权限的应用使用相同的证书签名的应用。请避免使用此选项,“signature”级别足以满足大多数需求,“signatureOrSystem”权限用于某些特殊情况

测试:新建两个应用,sendapp,thirdapp。在两个app中分别新建StaticReceiver1.java,StaticReceiver2.java,StaticReceiver3.java三个类,继承BroadcastReceiver并实现onReceiver方法,在清单文件中注册Receiver,其中sendapp的清单文件中加入权限,thirdapp中未加入权限。

<uses-permission android:name="com.example.permission.receiver" />

结果:只有sendapp中可以收到消息,thirdapp中不能收到消息。
(3)拦截广播:

abortBroadcast();

2.动态注册:
动态注册是在代码中通过设置 IntentFilter对象实现的,不需要在清单文件中注册 Receiver 。
(1)注册Receiver:

BroadcastReceiver receiver = new DynamicReceiver();IntentFilter intentFilter = new IntentFilter("com.liuwei.DynamicReceiver");registerReceiver(receiver, intentFilter);

(2)发送广播:

Intent intent = new Intent();               intent.setAction("com.liuwei.DynamicReceiver");sendBroadcast(intent);

(3)注销Receiver:

unregisterReceiver(receiver);

说明:
(1)对于动态广播,注册广播就必须注销广播,否则会导致内存泄露。
(2)动态广播最好在onResume()注册、onPause()注销。
因为onPause()在App死亡前一定会被执行,从而保证广播在App死亡前一定会被注销,从而防止内存泄露。

五.LocalBroadcastManager的使用

对于LocalBroadcastManager方式发送的应用内广播,只能通过LocalBroadcastManager动态注册,不能静态注册。

api 说明 LocalBroadcastManager.getInstance(this).registerReceiver(BroadcastReceiver, IntentFilter) 注册Receiver LocalBroadcastManager.getInstance(this).sendBroadcastSync(Intent) 发送同步广播 LocalBroadcastManager.getInstance(this).sendBroadcast(Intent) 发送异步广播 LocalBroadcastManager.getInstance(this).unregisterReceiver(BroadcastReceiver); 注销Receiver

1.注册Receiver:

LocalBroadcastManager manager = LocalBroadcastManager.getInstance(this);                LocalBroadcastManager localReceiver = new LocalReceiver();                IntentFilter intentFilter1 = new IntentFilter("com.liuwei.localManagerReceiver");                manager.registerReceiver(localReceiver, intentFilter1);

2.发送广播:

Intent intent = new Intent();                intent.setAction("com.liuwei.localManagerReceiver");manager.sendBroadcast(intent);

3.注销Receiver:

manager.unregisterReceiver(localReceiver);

LocalBroadcastManager除了能解决BroadcastReceiver进程间安全性问题外,相对Context操作的BroadcastReceiver而言还具有更高的运行效率。

六.生命周期

BroadcastReceiver 的生命周期很短,在执行 onReceiver() 方法时才有效,一旦执行完毕,该Receiver 的生命周期就结束了。
所以onReceive必须在10秒钟内执行完毕,否则会产生ANR(Application Not Response)。如果需要进行耗时的操作,可以通过启动一个Service来实现。

注意:

对于不同注册方式的广播接收器回调OnReceive(Context context,Intent intent)中的context返回值是不一样的:
对于静态注册(全局+应用内广播),回调onReceive(context, intent)中的context返回值是:ReceiverRestrictedContext;
对于全局广播的动态注册,回调onReceive(context, intent)中的context返回值是:Activity Context;
对于应用内广播的动态注册(LocalBroadcastManager方式),回调onReceive(context, intent)中的context返回值是:Application Context。
对于应用内广播的动态注册(非LocalBroadcastManager方式),回调onReceive(context, intent)中的context返回值是:Activity Context;
以上测试代码请点击这里。
参考文档:
https://developer.android.google.cn/guide/components/broadcasts.html
http://www.jianshu.com/p/f348f6d7fe59
http://www.jianshu.com/p/ca3d87a4cdf3

原创粉丝点击