安卓面试题: 3 - 关于 Broadcast 和 BroadcastReceiver

4,520 阅读3分钟
原文链接: www.iwfu.me

关于广播

自定义广播接收器的两种方式

  • 静态注册






在manifest里注册,当app退出后仍然可以接收到相应的广播。
– 动态注册

receiver = new BroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(CALL_ACTION);
context.registerReceiver(receiver, intentFilter);

在代码中注册,app退出后就接收不到广播。
自Android3.1开始,系统本身则增加了对所有app当前是否处于运行状态的跟踪。在发送广播时,不管是什么广播类型,系统默认直接增加了值为FLAG_EXCLUDE_STOPPED_PACKAGES的flag,导致即使是静态注册的广播接收器,对于其所在进程已经退出的app,同样无法接收到广播。

BroadCastReceiver 的生命周期

  • 广播接收者的生命周期非常短暂的,在接收到广播的时候创建, onReceive()方法结束之后销毁;
  • 广播接收者中不要做一些耗时的工作,否则会弹出 Application No Response 错误对话框;
  • 最好也不要在广播接收者中创建子线程做耗时的工作,因为广播接收者被 销毁后进程就成为了空进程,很容易被系统杀掉;
  • 耗时的较长的工作最好放在服务中完成;

Android 引入广播机制的用意

  • 从 MVC 的角度考虑(应用程序内) 其实回答这个问题的时候还可以这样问, android 为什么要有那 4 大组件,现在的移动开发模型基本上也是照搬的 web 那一套 MVC 架构,只不过是改了点嫁妆而已。android 的四大组件本 质上就是为了实现移动或者说嵌入式设备上的 MVC 架构,它们之间有时候 是一种相互依存的关系,有时候又是一种补充关系,引入广播机制可以方便 几大组件的信息和数据交互。
  • 程序间互通消息(例如在自己的应用程序内监听系统来电)
  • 效率上(参考 UDP 的广播协议在局域网的方便性)
  • 设计模式上(反转控制的一种应用,类似监听者模式)

其他

1.如何让自己的广播只让指定的 app 接收?
通过自定义广播权限来保护自己发出的广播。 在清单文件里receiver必须有这个权限才能收到广播。 首先,需要定义权限: 然后,声明权限: 这时接收者就能收到发送的广播。

2.广播的优先级对无序广播生效吗?
生效的

3.动态注册的广播优先级谁高?
谁先注册谁优先级高。

4.如何判断当前 BroadcastReceiver 接收到的是有序广播还是无序广播?
在 BroadcastReceiver 类中 onReceive()方法中,可以调用 boolean b = isOrderedBroadcast();判断接收到的广播是否为有序广播。

5.粘性广播有什么作用?怎么使用? 粘性广播主要为了解决,在发送完广播之后,动态注册的接收者,也能够收到广播。举个例子首先发送一广播,我的接收者是通过程序中的某个按钮动态注册的。如果不是粘性广播,我注册完接收者肯定无法收到广播了。这是通过发送粘性广播就能够在我动态注册接收者后也能收到广播。

在 android 5.0/api 21中deprecated,不再推荐使用,包括粘性有序广播

6.增加广播的安全性

  • 对于同一App内部发送和接收广播,将exported属性人为设置成false,使得非本App内部发出的此广播不被接收;
  • 在广播发送和接收时,都增加上相应的permission,用于权限验证;
  • 发送广播时,指定特定广播接收器所在的包名,具体是通过intent.setPackage(packageName)指定,这样此广播将只会发送到此包中的App内与之相匹配的有效广播接收器中。

面试题合集来自各个网站论坛等资源的整合,选取一些常见的面试知识点,有错误的地方请及时指出以尽快修改。