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

Android广播接收器

2016-01-09 11:14 573 查看
Android中的广播,即BroadcastReceiver,是应用开发中四大组件之一,通过发送/接收广播,可以实现不同组件的通信。

广播的分类

根据是否跨进程,可分为全局广播和本地广播。

全局广播:广播可以发送给不同进程,可以接收不同进程广播消息

本地广播:

使用LocalBroadcastManager.getInstance(context).sendBroadcast发送本地广播

使用本地广播相比全局广播有如下优势:

1.保护隐私: 广播的数据不会离开当前进程,不用担心数据会泄露;

2.安全: 其他应用不可能发送该广播给当前进程, 因此不用担心安全漏洞;

3.效率: 与全局广播在整个系统传播相比,本地广播效率更高;

根据广播接收顺序,可分为两类:

1.普通广播

- 通过Context.sendBroadcast发送

- 广播是以异步方式发送

- 广播的接收者运行顺序不确定

- 广播接收者不能使用彼此之间的结果,不能放弃广播



2.有序广播

- 通过Context.sendOrderedBroadcast发送

- 一次发送给一个接收者,接收者按顺序进行

- 当前广播接收者可以传递结果给下一个接收者

- 当前广播接收者可以放弃广播,则它后面的广播接收都将收不到该广播

- 可以通过设置android:priority属性控制广播接收的顺序,如果优先级相同则顺序不确定



普通广播又有:

1.粘性广播

- 可通过Context.sendStickyBroadcast发送粘性广播。

- 粘性广播发送的是消息是粘性的(sticky),Receiver如果在接收粘性广播前被销毁,那么下次重新创建时会再次接收到该广播。

- 发送粘性广播需要权限 android.permission.BROADCAST_STICKY

- 在onReceive中接收粘性广播:

if(isInitialStickyBroadcast){

//接收粘性消息

}else{

//接收新消息

}

2.定向广播

给指定的应用发送广播

Intent intent = new Intent(action);

intent.setComponent(new ComponentName(packageName,className));

sendBroadcast(intent);

安全问题

(1)Intent的命名空间是全局的。确保广播的Intent action只适用于你自己的命名空间中,否则可能和其他应用冲突。

(2)当使用registerReceiver(BroadcastReceiver, IntentFilter)注册广播接收者时,任何应用都有可能发送广播给该接收者。可以添加权限来控制谁可以给它发广播。

(3)在应用的manifest指定广播接收者并且指定intent-filters时,任何其他应用都可以给它发送广播而不管这个filter。为阻止其他应用给它发送广播,可使用android:exported="false"

(4)当使用sendBroadcast(Intent)或相关API时,一般情况任意其他应用都有可能收到广播。可以通过设置权限来控制谁可以接收该广播。从ICS开始,可以通过使用Intent.setPackage限制广播只发给单个应用。

所有以上问题在LocalBroadcastManager中都没有,因为广播的intent不会超出当前进程。

发送广播时强加权限,可以通过给sendBroadcast(Intent, String)或sendOrderedBroadcast(Intent, String, BroadcastReceiver, android.os.Handler, int, String, Bundle)

传递非空的权限参数来完成。只有拥有相应权限(在AndroidManifest.xml中使用<uses-permission>申请权限)的广播接收者才能收到发送的广播。

接收广播时强加权限,可以通过在注册广播时提供非空权限参数来完成(静态或动态注册都可以)。

只有拥有相应权限(在AndroidManifest.xml中使用<uses-permission>申请权限)的广播发送者才能给该接收者发送广播。

广播生命周期

一个BroadcastReceiver对象只在onReceive(Context, Intent)方法执行期间有效,一旦该方法返回,系统认为该对象已经结束,不再处于活动状态。

实现onReceive(Context, Intent) 方法时应注意,不要使用异步的操作,因为你需要在方法结束后调用异步处理程序,但那个时候广播接收器已经不处于活动状态,系统随时可以在异步操作完成之前杀掉进程。

特别是不要在广播接收器中显示对话框或绑定服务。对于前者,应使用NotificationManager API来代替,对于后者,可以使用Context.startService()启动服务。

onReceive方法运行在主线程(UI线程),因此不要做耗时操作,否则执行时间超过10s 会造成ANR现象。

当前运行广播(即当前执行广播接收器onReceive方法)的进程会被系统认为是前台进程,除非是内存极度不够的情况,否则系统不会杀掉该进程。

一旦onReceive方法返回,广播接收器不是活动状态,它的宿主进程的重要程度只和任何其他运行的应用组件一样。这点特别重要,因为假如进程只运行广播接收器,那么onReceive方法返回后系统认为该进程是空进程,从而容易杀掉它以便给其他更重要的进程提供更多资源。

这意味着对于长时间的操作,应该使用service,结合广播接收器以使整个操作期间进程处于活跃状态。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: