概述
BroadcastReceiver广播接收者,本质是一个全局的监听器,可以监听到各种广播,可以用来实现不同组件之间的通信。广播最大的特点就是发送方并不关心接收方是否接到数据,也不关心接收方是如何处理数据的,通过这样的形式来达到接、收双方的完全解耦合。
BroadcastReceiver种类
-
普通广播(Normal Broadcast)
普通广播完全是异步的,通过Context.sendBroadcast()方法发送,消息传递效率比较高,但所有接收器的执行顺序不确定。缺点是接收者不能将处理结果传递给下一个接收者,并且无法终止广播的传播。
-
有序广播(Ordered Broadcast)
有序广播是通过Context.sendOrderedBroadcast()方法发送,所有的广播者按照优先级依次执行,广播接收器的优先级通过receiver的intent-filter中的android:priority属性来设置,数值越大优先级越高。当广播接收器接收到广播后,可以使用setResult()方法把结果传递给下一个接收者,通过getResult()方法获取上一个接收者传递过来的结果,并可以通过abortBroadcast()方法丢弃该广播,使该广播不再传递给下一个接收者。
-
粘性广播(Sticky Broadcast)
粘性广播通过Context.sendStickBroadcast()方法来发送,用此方法发送的广播会一直滞留,当有匹配此广播的接收器被注册后,该广播接收器就会收到此广播。使用此广播时,需要获得BROADCAST_STICKY权限。
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
-
本地广播(Local Broadcast)
前三种广播都是全局广播,所有应用都可以接收到,这样就带来安全隐患,而本地广播只在进程内传播。用法很简单,只需要把调用Context的sendBroadcast、registerReceived、unregisterReceived的地方替换为LoaclBroadcastManager.getInstance(Context context)中对应的方法即可。
广播的注册方式
广播的注册方式有两种,静态注册和动态注册。
静态注册
- 注册方式
在AndroidManifest.xml里通过<receiver>标签声明 -
属性说明:
详情可以参看Google开发者网站上关于AndroidManifestReceiver的介绍。
- 注册步骤
1、定义BroadcastReceiver
public class MyBroadcastReceiver extends BroadcastReceiver {
private final static String TAG = "BRDemo";
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG,"onReceive = " + intent.getAction());
}
}
2、在manifest里面注册广播
<receiver android:name=".MyBroadcastReceiver"
android:label="MyBroadcastReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.android.peter.STATIC_BROADCASTRECEIVER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
当此 App首次启动时,系统会自动实例化MyBroadcastReceiver类,并注册到系统中。
03-13 23:59:12.689 1717-1779/system_process W/BroadcastQueue: Background execution not allowed: receiving Intent { act=com.android.peter.STATIC_BROADCASTRECEIVER cat=[android.intent.category.DEFAULT] flg=0x10 } to com.android.peter.broadcastreceiverdemo/.MyBroadcastReceiver
动态注册
- 注册方式:在代码中调用Context.registerReceiver()方法
\\1、声明并实例化BroadcastReceiver和IntentFilter
private IntentFilter mIntentFilter = new IntentFilter();
private MyBroadcastReceiver mBroadcastReceiver = new MyBroadcastReceiver();
\\2、在onCreate中设置接收的广播
mIntentFilter.addAction("com.android.peter.STATIC_BROADCASTRECEIVER");
mIntentFilter.addCategory("android.intent.category.DEFAULT");
\\3、在onResume中动态注册
registerReceiver(mBroadcastReceiver,mIntentFilter);
\\4、在onPause中注销广播
if(mBroadcastReceiver != null) {
unregisterReceiver(mBroadcastReceiver);
}
在onResume()注册、onPause()注销是因为onPause()在App退出的时候一定会被执行,从而保证广播一定会被注销,从而防止内存泄露。
附:发送广播代码
Intent intent = new Intent();
intent.setAction("com.android.peter.STATIC_BROADCASTRECEIVER");
intent.addCategory("android.intent.category.DEFAULT" );
sendBroadcast(intent);
两种注册方式的区别:
正式因为静态注册耗电、占内存、不受程序生命周期影响,所以Google在Android 8.0上禁止大部分广播的静态注册——Android 8.0新特性-取消大部分静态注册广播。
小结
本文介绍了BroadcastReceiver相关的基础知识,关于BroadcastReceiver是如何注册和接收广播的原理可以参看——Android四大组件——BroadcastReceiver(原理篇)。