Broadcast是Android内部通信机制的一个重要方式,包括广播发送者,广播接受者,信息,可以类似于传统意义上的收音机,由电台(广播发送者)发送信息(Intent),由收音机等接收设备接受信息(广播接受者)。发送方发送完消息无需关心消息是否被接收。

1. 应用场景以及广播分类

1.1 应用场景

  1. 同一app内部的同一组件内的消息通信(单个或多个线程之间);
  2. 同一app内部的不同组件之间的消息通信(单个进程);
  3. 同一app具有多个进程的不同组件之间的消息通信;
  4. 不同app之间的组件之间消息通信;
  5. Android系统在特定情况下与App之间的消息通信。

1.2 广播分类

  • 普通广播(Normal Broadcast)

    通过Context.sentBroadcast()发送,接收顺序不确定,无法终止传递,知道没有匹配的接收器。

  • 有序广播(Ordered Broadcast)

    通过Context.sendOrderBroadcast()发送,receiver根据intent-filter中的android:priority属性确定优先级接收,每个receiver接收到广播后可以通过setResult()设置结果传递给下一个receiver,后者通过getResult()方法获取上一个传递的数据,可以通过abortBroadcast()让系统丢弃广播,不再传递。

  • 粘性广播(Sticky Broadcast)

    通过Context.sentStivkyBroadcast()发送广播,发送广播后会一直滞留,当有匹配次广播接收器被注册后,该广播接收器会受到此广播,需要申明权限:

    1
    <uses-perimission android:name="android.permission.BROADCAST_STICKY">
在Android 5.0之后弃用,不推荐使用
  • 本地广播(Local Broadcast)

    Support v4包中的广播方式,需要使用LocalBroadcastManager操作。

    LocalBroadcastManager是单例模式的,通过LocalBroadcast.getInstance(context)获取实例,其中方法跟Context的广播类似,主要有sendBroadcast、registerBroadcast、registerReceiver、unregusterReceiver。

  • 系统广播(System Broadcast)

2. 广播机制原理

广播机制是一个典型的观察者模式,也就是发布-订阅模式。

广播流程:

  1. 广播接收者通过Binder机制在AMS(Activity Manager Service)中注册
  2. 广播发送者通过Binder机制像AMS发送广播
  3. AMS根据广播发送者的要求,在注册列表中,通过IntentFilter查找合适的广播接受者
  4. AMS将广播发送到广播接收者相应的消息循环队列
  5. 广播接收者通过消息循环拿到广播

3. 广播接收者BroadcastReceiver

BroadcastReceiver是用于接收广播发送者发出的广播,需要继承BroadcastReceiver类,需要实现onReceiver()方法。

不管什么方式,都需要继承BroadcastReceiver类,并实现方法。

1
2
3
4
5
6
7
public class MyBroadcastReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
// 接收到广播后,则自动调用该方法
}
}

3.1 注册BroadcastReceiver

广播接收器注册分为静态注册动态注册

3.1.1 静态注册

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<receiver 
android:enabled=["true" | "false"]
<!-- 能否接收其他App的发出的广播 -->
android:exported=["true" | "false"]
android:icon="drawable resource"
android:label="string resource"
<!-- 继承BroadcastReceiver子类的类名 -->
android:name=".mBroadcastReceiver"
<!-- 具有相应权限的广播发送者发送的广播才能被此BroadcastReceiver所接收 -->
android:permission="string">
<!-- intent过滤器,指定可以匹配哪些intent, 一般需要定义action 可以是自定义的也可是系统的 -->
<intent-filter>
<action android:name="com.tolcol.app.broadcast.action" />
</intent-filter>
</receiver>

3.1.2 动态注册

在Context中调用Context.registerReceiver()注册

1
2
3
4
5
6
7
8
9
10
11
12
13
private void doRegisterReceiver(){
MyBroadcastReceiver mBroadcastReceiver = new MyBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.tolcol.app.broadcast.action");
registerReceiver(mBroadcastReceiver, intentFilter);
}

@Override
protected void onPause() {
super.onPause();
//销毁广播
unregisterReceiver(mBroadcastReceiver);
}