概述
该组件本质上是一种全局的监听器,用于监听系统全局的广播消息。
用于接收应用App发出的广播消息,并做出响应。
实现BroadcastReceiver方法很简单,只需要重写它的onReceive(Context context,Intent intent)方法即可。
生命周期很短。当系统Broadcast事件发生后,系统会创建对应的BroadcastReceiver的实例,并自动触发onReceive()方法,当该方法执行完后,BroadcastReceiver的实例就会被销毁。
如果onReceive()方法不能在10s内执行完成,会弹出ANR,因此不要在该方法中执行一些耗时的操作。
应用场景
不同组件之间的通信(App内/不同App之间)
多线程通信
注册方式
- 静态注册:在AndroidManifest.xml文件中配置。
<receiver
<!--继承BroadcastReceiver子类的类名-->
android:name=".MyReceiver"
<!--是否启用此broadcastReceiver-->
android:enabled="true"
<!--此broadcastReceiver能否接收其它App发出的广播,对于有intent-filter情况下默认值为true-->
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</receiver>
- 动态注册:在代码中调用Context.registerReceiver(BroadcastReceiver receiver, IntentFilter filter)方法。
MyReceiver receiver = new MyReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);
//IntentFilter intentFilter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(receiver , intentFilter);
//unregisterReceiver(receiver);
动态注册最好在Activity的onResume()注册,onPause()注销。
区别:
静态注册:应用程序关闭后,如果有广播来,依旧会被调用。不受任何组件的生命周期影响。需要时刻监听广播。
动态注册:跟随组件的生命周期变化,在组件结束前必须移除广播接收器。需要特定时刻监听广播。
注意:Android 8.0对广播进行了限制。因此当使用静态注册失效时,可以改成动态注册方式。
来源:https://developer.android.google.cn/about/versions/oreo/background
广播类型:
-
普通广播(Normal Broadcast):是完全异步的,可以在同一时刻被所有接收者接收到,消息传递的效率比较高,且无法被截断。缺点是不能传递。
普通广播发送只需要调用Context的sendBroadcast(Intent intent)方法即可,该广播将会启动intent参数所对应的BroadcastReceiver。
Intent intent = new Intent();
intent.setAction("android.intent.action.BOOT_COMPLETED");
sendBroadcast(intent);
有序广播(Ordered Broadcast):是一种同步执行的广播。在广播发出后同一时刻只有一个广播接收器能够接收到, 优先级高的广播接收器会优先接收,当优先级高的广播接收器的 onReceiver() 方法运行结束后,广播才会继续传递,且前面的广播接收器可以选择截断广播。
(1) 优先级别声明在<intent-filter.../>元素的android:priority属性中,数越大优先级别越高。也可调用IntentFilter对象的setPriority()进行设置。
(2) 优先级的大小设置范围为-1000~1000。
(3) 发送广播调用sendOrderedBroadcast()方法。
(4) 可以调用setResultExtras(bundle)方法存入数据使得下一个广播能够接收。
(5) 在onReceiver() 方法中调用aboryBroadcast()方法截断广播,使得不再传递下去。本地广播(Local Broadcast):
之前所说的都是属于全局广播,即发出的广播可以被其它应用接收到,也可以接收其它应用发出的广播,会存在数据安全问题。
在某些情况下,使用本地广播,该广播只能在应用内部进行传递,而且也只能接收本应用内发出的广播。
实现1:全局广播 --> 本地广播
(1) 注册广播时将exported属性设置为false,使得非本应用内部发出的此广播不被接收。
(2) 在广播发送和接收时,增设相应权限permission,用于权限验证。
(3) 发送广播时指定该广播接收器所在的包名,此广播将只会发送到此包中的应用内与之相匹配的有效广播接收器中。
实现2:使用LocalBroadcastManager类
注册时调用LocalBroadcastManager的registerReceiver方法替代全局广播调用context的registerReceiver方法。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(this);
localReceiver = new LocalReceiver();
IntentFilter filter = new IntentFilter(LOCAL_ACTION);
manager.registerReceiver(localReceiver, filter);
}
@Override
protected void onDestroy() {
super.onDestroy();
localBroadcastManager.unregisterReceiver(localReceiver);
}
public void sendLocalBroadcast(View view) {
Intent intent = new Intent(LOCAL_ACTION);
localBroadcastManager.sendBroadcast(intent);
}
- 系统广播(System Broadcast)
Android的大量系统事件都会对外发送标准广播。以下是常见的广播Action:
- android.net.conn.CONNECTIVITY_CHANGE:监听网络变化
- Intent.ACTION_AIRPLANE_MODE_CHANGED:关闭或打开飞行模式时的广播
- Intent.ACTION_BOOT_COMPLETED:在系统启动完成后,这个动作被广播一次(只有一次)
- Intent.ACTION_DATE_CHANGED:系统日期发生改变
- Intent.ACTION_TIME_CHANGED:系统时间发生改变
- Intent.ACTION_TIMEZONE_CHANGED:系统时区发生改变
- Intent.ACTION_LOCALE_CHANGED:设备当前区域设置已更改
- Intent.ACTION_BATTERY_CHANGED:充电状态,或者电池的电量发生变化
- Intent.ACTION_BATTERY_LOW:表示电池电量低
- Intent.ACTION_BATTERY_OKAY:表示电池电量充足,即从电池电量低变化到饱满
- Intent.ACTION_CONFIGURATION_CHANGED:设备当前设置被改变时(包括:界面语言,设备方向,等)
- Intent.ACTION_REBOOT:重启设备
- Intent.ACTION_SCREEN_OFF:屏幕被关闭
- Intent.ACTION_SCREEN_ON:屏幕被打开
- Intent.ACTION_SHUTDOWN:关闭系统