Android BroadCast

Android apps can send or receive broadcast messages from the Android system and other Android apps, similar to the publish-subscribe design pattern. These broadcasts are sent when an event of interest occurs. For example, the Android system sends broadcasts when various system events occur, such as when the system boots up or the device starts charging. Apps can also send custom broadcasts, for example, to notify other apps of something that they might be interested in (for example, some new data has been downloaded).

上述是Android对于BroadCast的官方解释,从这里可以看出Broadcast是一种广泛运用的在应用之间传输信息的机制,Android中我们要发送的广播内容是一个Intent,这个Intent携带了我们要传输的数据。

在Android系统中,为什么需要广播机制呢?广播机制,本质上它就是一种组件间的通信方式,如果是两个组件位于不同的进程当中,那么可以用Binder机制来实现,如果两个组件是在同一个进程中,那么它们之间可以用来通信的方式就更多了,这样看来,广播机制似乎是多余的。然而,广播机制却是不可替代的,它和Binder机制不一样的地方在于,广播的发送者和接收者事先是不需要知道对方的存在的,这样带来的好处便是,系统的各个组件可以松耦合地组织在一起,这样系统就具有高度的可扩展性,容易与其它系统进行集成。

在软件工程中,是非常强调模块之间的高内聚低耦合性的,不然的话,随着系统越来越庞大,就会面临着越来越难维护的风险,最后导致整个项目的失败。Android应用程序的组织方式,可以说是把这种高内聚低耦合性的思想贯彻得非常透彻,在任何一个Activity中,都可以使用一个简单的Intent,通过startActivity或者startService,就可以把另外一个Activity或者Service启动起来为它服务,而且它根本上不依赖这个Activity或者Service的实现,只需要知道它的字符串形式的名字即可,而广播机制更绝,它连接收者的名字都不需要知道。


1. 广播使用场景

  • 同一APP具有多个进程的不同组件之间的消息通信
  • 不同app之间的组件之间的消息通信

2. 广播种类

1. Normal BroadCast:Context.sendBroadCast

无序广播:该广播调用sendBroadCast()方法来发送广播的。无序广播不可以被拦截,若被拦截,则会报错。所有接受无序广播的广播接收者在此广播被发送时均能接收到该无序广播。无序广播的广播接收者之间不能相互传递数据。

2. System BroadCast:Context.sendOrderedBroadCast

有序广播:该广播是调用sendOrderedBroadCast()方法来发送广播的,同时也可以调用abortBroadcast()方法来拦截该广播。有序广播的广播接收者可以在清单文件中,通过<intent-filter>标签设置"android:property"属性来设置优先级,优先级高的接收者可以拦截优先级低的。
在相同优先级下,广播接收者接受的顺序要看接收者在清单文件中声明的顺序,先声明的接收者比后声明的接收者要先接收到广播。有序广播的广播接收者之间可以互相传递数据。

3. Local BroadCast:只在自身app内传播


3. 广播接收者的注册方式

1. 静态注册

直接在AndroidManifest.xml文件中进行注册,通过该方式注册的广播接收者在系统中运行一次后就会被注册到系统中,以后无须运行该应用程序也可以就收到广播。

2. 动态注册

无须在AndroidManifest.xml文件中注册<receiver>组件,直接在代码中通过调用Context的registerReceiver()方法即可在程序中动态注册广播接收者。通过这种注册方式注册的广播接收者,只有在代码运行时,广播接收者才生效。若代码运行结束,则广播接收者也即失效。


4. 内部实现机制

转自:Android四大组件:BroadcastReceiver史上最全面解析

  1. 自定义广播接收者BroadcastReceiver,并复写onReceive()方法;
  2. 通过Binder机制向AMS进行注册;
  3. 广播发送者通过Binder机制向AMS发送广播;
  4. AMS查找符合相应条件(IntentFilter/Permission等)的BroadcastReceiver,将广播发送到BroadcastReceiver(一般情况下是Activity)相应的消息循环队列中;
  5. 消息循环执行拿到此广播,回调BroadcastReceiver中的onReceive()方法。

5. LocalBroadCastManager

  1. 使用它发送的广播将只在自身App内传播,因此不必担心泄露隐私数据;
  2. 其他App无法对你的App发送该广播,因为你的App根本就接收不到非自身应用发送的该广播,因此不必担心安全漏洞问题;
  3. 比系统的全局广播更加高效
  1. localBroadcastManager高效的原因主要是因为它内部是通过Handler实现的,它的sendBroadcast()其实是通过handler发送一个Message实现的;
  2. 相比与系统方便通过Binder实现肯定是高效,同时使用Handler来实现,别的应用无法向我们的应用发送该广播,而我们应用内发送的广播也不会离开我们的应用;
  3. localBroadcastManager内部协作主要是靠mReceivers和mActions这两个Map集合,当然还有一个List集合mPendingBroadcasts,这个主要是存储待接收的广播对象。

6. 其他

关于BroadcastReceiver使用需要注意的几点:

  • onReceive中不能执行耗时操作,如果耗时超过10s会弹出ANR。
  • onReceive中context参数,如果是静态注册的广播,context为ReceiverRestrictedContext,所在如果在这里要启动一个Activity的话(调用startActivity),需要在intent中添加Intent.FLAG_ACTIVITY_NEW_TASK;如果是动态注册的广播,context为当前注册时所在的组件,比如Activity或者Service。
  • 监听系统广播,需要在AndroidManifest中申请权限,此外,Android高版本系统对于一些重要的系统广播,比如开机启动,网络连接,电量变化,锁屏等做了限制,如果需要监听这些广播,需要做系统兼容性处理。
  • 普通广播的广播接收器是并行无序执行的,有序广播的广播接收器按照广播优先级串行执行

参考并感谢

  1. Android四大组件:BroadcastReceiver史上最全面解析
  2. Broadcast使用场景解读