BroadcastReceiver的概念
1、系统在产生某个事件时发送广播,应用程序使用广播接收者接收这个广播,就知道系统产生了什么事件
2、本质上是全局的监听器,监听全局的广播消息(网络变化、收发短信、电量改变等等)
BroadcastReceiver的作用
1、监听 / 接收 应用 App
发出的广播消息,并 做出响应
BroadcastReceiver的生命周期
1、从创建后对象调用开始,到onReceiver方法执行完成之后结束。另外,每次广播被接收后会重新创建BroadcastReceiver对象,并在onReceiver方法中执行完就销毁,如果BroadcastReceiver的onReceiver方法中不能在10秒内执行完成,Android会出现ANR异常。所以不要在BroadcastReceiver的onReceiver方法中执行耗时的操作
2、如果需要在BroadcastReceiver中执行耗时的操作,可以通过Intent启动Service来完成
BroadcastReceiver实现原理
1、Android
中的广播使用了设计模式中的观察者模式:基于消息的发布 / 订阅事件模型因此,Android将广播的发送者 和 接收者 解耦,使得系统方便集成,更易扩展
BroadcastReceiver的使用
1、自定义广播接受者BroadcastReceiver
1.1、继承BroadcastReceiver基类
1.2、必须复写抽象方法onReceive()方法
以接收系统自带网络广播为列
class NetworkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Toast.makeText(context, "网络改变",
// Toast.LENGTH_SHORT).show();
Toast.makeText(context, "接收的广播为:" + intent.getAction() + "接收的信息为:" + intent.getStringExtra("msg"),
Toast.LENGTH_SHORT).show();
binding.tv.setText(String.valueOf(intent.getStringExtra("msg")));
}
}
1.3、BroadcastReceiver注册方式(静态注册、动态注册)
1.3.1、静态注册
在manifest中注册
<receiver
//此广播接收者类是NetworkChangeReceiver
android:name=".NetworkChangeReceiver" >
//用于接收网络状态改变时发出的广播
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
app启动时会自动实例化NetworkChangeReceiver类并注册到系统中
1.3.2、动态注册
在代码中使用Context.registerReceiver()
方法
封装成方法放到onCreate()中
//系统广播
private void initBroadcastReceiver() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
// intentFilter.addAction("com.example.broadcastreceiverdemo.mainactivity.SEND_MESSAGE");
NetworkChangeReceiver networkChangeReceiver = new NetworkChangeReceiver();
//动态注册广播 最后要记得,动态注册的广播接收器一定都要取消注册才行
registerReceiver(networkChangeReceiver, intentFilter);
}
销毁注册的广播
// 注册广播后,要在相应位置记得销毁广播
// 即在onDestroy() 中unregisterReceiver(mBroadcastReceiver)
// 当此Activity实例化时,会动态将MyBroadcastReceiver注册到系统中
// 当此Activity销毁时,动态注册的MyBroadcastReceiver将不再接收到相应的广播。
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(networkChangeReceiver);
}
*也可在Activity 的 onResume()注册、onPause()注销
1.4、两种注册方式的区别
注册方式 | 区别 | |||
使用方式 | 特点 | |||
静态注册 (常驻广播) | 在Androidmanifest.xml里通过<receive>标签声明 | 常驻,不受任何组件的生命周期影响(应用程序关闭后如果有信息广播来,程序依旧会被系统调用) 缺点:耗电,占内存 应用:需要时刻监听 | ||
动态注册 (非常驻广播) | 在代码中调用Context.registerReceiver()方法 | 非常驻,灵活跟随组件的生命周期变化 应用:需要特定时刻监听 |
Local BroadcastManager(App应用内广播)
优点:
1、因广播数据在本应用范围内传播,你不用担心隐私数据泄露的问题。
2、不用担心别的应用伪造广播,造成安全隐患。
3、相比在系统内发送全局广播,它更高效。
1.1、Android中的广播可以跨App直接通信(exported对于有intent-filter情况下默认值为true)
1.2、通用广播不足:
1.2.1、其他App针对性发出与当前App intent-filter相匹配的广播,由此导致当前App不断接收广播并处理;
1.2.2、其他App注册与当前App一致的intent-filter用于接收广播,获取广播具体信息;
即会出现安全性 & 效率性的问题。
1.3、具体使用
1.3.1、注册广播时将exported属性设置为false,使得非本App内部发出的此广播不被接收;
1.3.2、在广播发送和接收时,增设相应权限permission,用于权限验证;
1.3.3、发送广播时指定该广播接收器所在的包名,此广播将只会发送到此包中的App内与之相匹配的有效广播接收器中。
通过intent.setPackage(packageName)指定报名
注:对于LocalBroadcastManager方式发送的应用内广播,只能通过LocalBroadcastManager动态注册,不能静态注册
//注册应用内广播接收器
//步骤1:实例化BroadcastReceiver子类 & IntentFilter mBroadcastReceiver
MyBroadcastReceiver mBroadcastReceiver = new MyBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
//步骤2:实例化LocalBroadcastManager的实例
localBroadcastManager = LocalBroadcastManager.getInstance(this);
//步骤3:设置接收广播的类型
intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);
//步骤4:调用LocalBroadcastManager单一实例的registerReceiver()方法进行动态注册
localBroadcastManager.registerReceiver(mBroadcastReceiver, intentFilter);
//取消注册应用内广播接收器
localBroadcastManager.unregisterReceiver(mBroadcastReceiver);
//发送广播类中编写
//发送应用内广播
Intent intent = new Intent();
intent.setAction(BROADCAST_ACTION);
localBroadcastManager.sendBroadcast(intent);