sendBroadcast 与 sendStickyBroadcast 的区别
前提条件:此处我主要讨论两种广播在代码中动态注册时的一些细节问题。
正常情况下,广播通常都是执行一次注册代码,就会触发各接收器接收一次,无论是在
onCreate 里注册还是 onResume 里注册:若在 onCreate 里注册,一般我们在
onDestroy 中进行注销;若在 onResume 里注册,一般我们在 onPause 里进行注销。
sendBroadcast 为普通广播,若是动态注册的话:
只有先注册再发送广播,发送出来的 intent 才可以被接收器接收到,并执行接收器对
象中的 onReceive 方法;若广播先发出来,再注册,广播先前发出来的 intent 是无法被
接收器接收到的,也无法执行其 onReceive 方法。
sendStickyBroadcast 广播,若是动态注册的话:
与 sendBroadcast 不同的是,sendStickyBroadcast 无论是先注册再发送还是先发
送再注册,发送出来的 intent 均可以被接收器接收到。当然你在使用
sendStickyBroadcast 广播时,首先需要在 manifest.xml 文件中配置此类型广播权限
<uses-permission
android:name="android.permission.BROADCAST_STICKY"/>。
具体说明如下:
1、在注册之前广播就发送出来了的 intent 会被缓存在内存中,待广播一旦注册该 intent
就会被接收器接收,并执行 onReceive 方法;
2、若注册之后广播发送出来,触发接收器接收 intent,接收器首先会去检索系统缓存中
是否存在 intent 对象,若系统中不存在缓存的 intent,广播 intent 发送过来时,系
统会先将其保留到缓存中,接收器会接收当前的 intent;若系统中已存在缓存的
intent,则接收器首先会接收缓存中保存的 intent,再接着接收当前发送过来的
intent,即此时会执行两次广播接收器 onReceive 方法,为避免重复执行广播接收器,
可以在 onReceive 方法中调用 removeStickyBroadcast(intent)方法,将缓存中的
intent 移除。这样下次接收器检索不到缓存中的 intent,就直接接收广播发送过来的
intent;
3、若当前广播为 sendStickyBroadcast,然后代码中改为普通广播,这时缓存中保存的
intent 依然会被接收器接收,再接收当前发送过来的 intent,效果和
sendStickyBroadcast 一样,哪怕清除应用本身的数据也还是如此,缓存中的 intent
对象依然存在。另一种现象是此时若先发送普通广播,再注册,此时普通广播的接收
器虽然接收不到发送过来的广播,但可以接收到先前使用 sendStickyBroadcast 广
播时缓存中的 intent,当然这种奇异现象只会出现在调试代码的情况下,是不会出现
在应用本身的执行过程中。该缓存中的 intent 对象只有在重启手机的情况下才会被销
毁或者当内存不足,系统自动销毁。
4、缓存中的 intent 对象对应不同的 action,若通过 sendStickyBroadcast 发送广播设
置不同的 action 值,将会在系统中分别对不同的 action 缓存不同的 intent 对象;即,
若设置 StickyBroadcast 的 action 为 A,则发送广播后会在系统中缓存一个对应的
intentA 对象,若设置 StickyBroadcast 的 action 为 B,则发送广播后会在系统中缓
存一个对应的 intentB 对象;这些缓存中的 intent 对象只有在重启手机的情况下才会
被销毁或者当内存不足,系统自动销毁。