Q:
BroadcastReceiver的生命周期
A:其实它只有一个onReceiver,不过面试官想考察的并不是它的生命周期,而是你对广播是否真正掌握,下面一并讲解下。
1、只有一个onReceiver, 相当的短暂,方法完成后广播接受者 就销毁,发送一次调用一次。
2、接受者不要做耗时操作,否则出现ANR。
3、也不要开启子线程进行耗时操作,因为生命周期结束后 整个进程就变进程了,容易被系统杀掉。
4、耗时较长的工作最好放在服务里。
Q:
BroadCastReceiver的注册方式有哪些?异同点?
A: 注册方式:
一种是在代码当中注册,注册的方法是registerReceiver(receiver,filter)(用Activity的实例来调用),取消注册的方法:unregisterReceiver(receiver),如果一个BroadcastReceiver用于更新UI(User Interface),那么通常会使用这种方法进行注册,在Activity启动的时候进行注册,在Activity不可见后取消注册;另一种就是在 AndroidManifest当中进行注册。
异同:
在AndroidManifest中进行注册后,不管改应用程序是否处于活动状态,都会进行监听,比如某个程序时监听内存的使用情况的,当在手机上安装好后,不管改应用程序是处于什么状态,都会执行改监听方法中的内容。
在代码中进行注册后,当应用程序关闭后,就不再进行监听。我们读知道,应用程序是否省电,决定了该应用程序的受欢迎程度,所以,对于那些没必要在程序关闭后仍然进行监听的Receiver。
Q:
BroadcastReceiver的安全性问题 ?
A:BroadcastReceiver的设计初衷就是从全局考虑的,
可以方便应用程序和系统、应用程序之间、应用程序内的通信
,所以对单个应用程序而言BroadcastReceiver是存在安全性问题的,相应问题及解决如下:
1、当应用程序发送某个广播时系统会将发送的Intent与系统中所有注册的BroadcastReceiver的IntentFilter进行匹配,若匹配成功则执行相应的onReceive函数。可以通过类似sendBroadcast(Intent, String)的接口在发送广播时指定接收者必须具备的permission。或通过Intent.setPackage设置广播仅对某个程序有效。
2、
当应用程序注册了某个广播时,即便设置了IntentFilter还是会接收到来自其他应用程序的广播进行匹配判断
。对于动态注册的广播可以通过类似registerReceiver(BroadcastReceiver, IntentFilter, String, android.os.Handler)的接口指定发送者必须具备的permission,对于静态注册的广播可以通过android:exported=”false”属性表示接收者对外部应用程序不可用,即不接受来自外部的广播。
3、上面两个问题其实都可以通过LocalBroadcastManager来解决。
4、使用android:protectionLevel;
Q:
BroadcastReceiver的分类 ?
A:BroadcastReceiver可以分为普通和有序两种。
通过Context.sendBroadcast发送的广播即为普通广播,对于普通广播接收者接收到它的顺序是不定的,所以接收者接收到后无法使用其他接收者对它的处理结果也无法停止它。
通过Context.sendOrderedBroadcast发送的广播即为有序广播,与普通广播的不同在于,接收者是有序接收到广播的并且可以对广播进行修改或是取消广播向下传递。系统根据接收者定义的优先级顺序决定哪个接收者先接收到它,接收者处理完后可以将结果传递给优先级低的接收者也可以停止广播使得其他优先级低的接收者无法接收到该广播。优先级通过android:priority属性定义,数值越大优先级别越高,取值范围:-1000到1000,虽然API文档介绍对sendBroadcast发送的广播无效,不过本人测试同样有效,相同优先级的接收者接收到广播的顺序随机。Android系统收到短信、接到电话后发送的广播都是有序广播,所以可以进行短信或电话的拦截,即取消广播。
PS:有序广播可以在onReceive函数中通过BroadcastReceiver的abortBroadcast接口(这个接口对sendBroadcast发送广播无效)取消广播,通过接口sendOrderedBroadcast(Intent, String, BroadcastReceiver, android.os.Handler, int, String, Bundle)发送的广播即便优先级高的广播取消了广播,接口参数中指定的BroadcastReceiver依然可以在其他接收者处理完后接收到广播。通过BroadcastReceiver的getResultExtras接口获得结果的Bundle再通过Bundle的putString和getString方法修改或获取数据。
Q:
有哪些特殊的BroadcastReceiver?
A:
1、LocalBroadcastManager本地广播
android引入了LocalBroadcastManager解决安全性介绍的一些问题,LocalBroadcastManager除了能解决BroadcastReceiver进程间安全性问题外,相对Context操作的BroadcastReceiver而言还具有更高的运行效率。
使用LocalBroadcastManager需要引入Android Support Library,如何引入见Add Support Package。
本地广播通过LocalBroadcastManager.getInstance(context).sendBroadcast(intent)发送广播,LocalBroadcastManager.getInstance(context).registerReceiver注册服务,通过LocalBroadcastManager.getInstance(context).unregisterReceiver取消注册服务,其他同普通广播.
2、
Sticky Broadcast粘性广播
如果发送者发送了某个广播,而接收者在这个广播发送后才注册自己的Receiver,这时接收者便无法接收到刚才的广播,为此Android引入了
StickyBroadcast
,在广播发送结束后会保存刚刚发送的广播(Intent),这样当接收者注册完Receiver后就可以继续使用刚才的广播。如果在接收者注册完成前发送了多条相同Action的粘性广播,
注册完成后只会收到一条该Action的广播,并且消息内容是最后一次广播内容
。系统网络状态的改变发送的广播就是
粘性广播
。
粘性广播
通过Context的sendStickyBroadcast(Intent)接口发送,需要添加权限
uses-permission android:name=”android.permission.BROADCAST_STICKY”
也可以通过Context的removeStickyBroadcast(Intent intent)接口移除缓存的粘性广播。
3、OrderedBroadcastReceiver有序广播
接收者有序接收广播并可以修改广播结果或是取消广播,通过Context的sendOrderedBroadcast接口发送。
4、StickyOrderedBroadcast粘性有序广播
这个就是粘性广播和有序广播的结合了,通过Context的sendStickyOrderedBroadcast接口发送。