Android基础-Broadcast
Broadcast是Android内部通信机制的一个重要方式,包括广播发送者,广播接受者,信息,可以类似于传统意义上的收音机,由电台(广播发送者)发送信息(Intent),由收音机等接收设备接受信息(广播接受者)。发送方发送完消息无需关心消息是否被接收。
1. 应用场景以及广播分类
1.1 应用场景
- 同一app内部的同一组件内的消息通信(单个或多个线程之间);
- 同一app内部的不同组件之间的消息通信(单个进程);
- 同一app具有多个进程的不同组件之间的消息通信;
- 不同app之间的组件之间消息通信;
- 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. 广播机制原理
广播机制是一个典型的观察者模式,也就是发布-订阅模式。
广播流程:
- 广播接收者通过Binder机制在**AMS(Activity Manager Service)**中注册
- 广播发送者通过Binder机制像AMS发送广播
- AMS根据广播发送者的要求,在注册列表中,通过IntentFilter查找合适的广播接受者
- AMS将广播发送到广播接收者相应的消息循环队列中
- 广播接收者通过消息循环拿到广播
3. 广播接收者BroadcastReceiver
BroadcastReceiver是用于接收广播发送者发出的广播,需要继承BroadcastReceiver类,需要实现onReceiver()方法。
不管什么方式,都需要继承BroadcastReceiver类,并实现方法。
|
|
3.1 注册BroadcastReceiver
广播接收器注册分为静态注册和动态注册
3.1.1 静态注册
<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()注册
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);
}