Android的Broadcast Receiver

来源:互联网 发布:excel表格怎么合计数据 编辑:程序博客网 时间:2024/04/28 00:28
  Broadcast Receiver最主要的功能还是处理系统事件。系统在启动完毕、电池电量发生变化、收到短信等等情况时都会发出系统事件,Receiver接收到这些事件并处理,它是应用和系统的一种交互接口(从概念上来说是Observer机制)。

  系统和应用是一对多的关系,所以系统发送事件时采用的是广播方式,而系统的这种广播通路是开放的,所以应用也可以通过它来广播发送自定义事件,这样一来就相当于也是应用和应用之间或者应用各Component之间的一种交互方式了。
  广播通路对应的方法是sendBroadcast()方法,sendBroadcast()的本质和startActivity()/startService()一样,其实都是把Intent传递给Framework的Activity Manager(Intent是个好东西,又是Parcelable,又是Cloneable的,很适合进程间传递,系统用它来作为事件的载体)。Activity Manager会负责解析Intent(其中会利用Package Manager之类),得到想要的Component,然后执行它,并把Intent传给它。相对于Activity和Service,Receiver算是轻量级的了,只是简单执行一个onReceive()方法就结束了。而且还有时间限制,如果超过10秒,系统就会弹出ANR对话框,要求结束它。也因为Receiver的简洁,系统多提供了一种动态注册的方式,应用可以在代码中注册Receiver,而不是在AndroidManifest.xml文件中静态注册(所以有时在xml文件中搜不到)。比较而言,静态注册的,不用考虑Component状态,比较简单;动态注册的,相对灵活,只是需要注意注册Receiver和注销Receiver配套。

  广播的方式则分成普通的和有序的。普通的简单,各个Receiver之间互不依赖,可以同时执行;有序的(sendOrderedBroadcast())则需要一个接一个执行,优先级高的先执行,先执行的可以中断广播,这样优先级低的Receiver将不再执行,另外执行结果也能传递,也就是说各个Receiver之间是相互关联的。
  关于优先级,IntentFilter类的setPriority()方法有说明,缺省值为0, 最大值为1000(SYSTEM_HIGH_PRIORITY),最小值为-1000(SYSTEM_LOW_PRIORITY)。数值越大优先级越高,数值相同就没啥意义了,说明应用不是特别关心其优先级(难道上千个等级还不够用?),或者涉及其他应用,不是应用自己所能决定。(另外,从概念上来说,相同数值的,动态注册的Receiver的优先级更高,Android的Framework的代码也是如此实现的,不过依赖这个还不如设置不同的数值)
  有意思的是系统还提供一种Sticky类型的广播方式(sendStickyBroadcast()/sendStickyOrderedBroadcast()/removeStickyBroadcast()),这种广播方式发出的事件被处理完后不会马上被销毁,新的Receiver注册后可以得到最近广播发出的事件,相当于有个全局静态变量了。这种类型的事件适合用来查询当前的一些系统状态,譬如查询当前电量,可以用registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED);得到对应的Intent,继而得到电量的相关数据。
  还有应用也可以进行同步式的广播(sendBroadcastSync()),这样在广播事件被处理完之前当前线程会被阻塞住。

  另外,最新的Support Package还提供了LocalBroadcastManager类,使用它可以限制在应用内部广播,提升了一些安全性。