介绍
- BroadcastReceiver(广播接收器),属于 Android 四大组件之一
Android广播机制简介
在Android中,有一些操作完成以后,会发送广播,比如说发出一条短信,或打出一个电话,如果某个程序接收了这个广播,就会做相应的处理。这个广播跟我们传统意义中的电台广播有些相似之处。之所以叫做广播,就是因为它只负责“说”而不管你“听不听”,也就是不管你接收方如何处理。另外,广播可以被不只一个应用程序所接收,当然也可能不被任何应用程序所接收。
作用以及运用场景
- 监听/接收应用app发出的广播消息,并作出回应
- 实现应用内广播通知
- 实现不同应用之间的广播通知
- 监听系统应用发出的广播
广播原理
1.广播接收者(消息订阅者)通过Binder机制在AMS中注册
2.广播发布者(消息发布这)通过Binder机制向AMS发送广播
3.AMS(处理中心)根据消息发布者的要求,在已经注册的列表中,寻找合适的广播接收者(寻找依据intentFilter/Permission)
4.AMS(处理中心)将广播发送到合适的广播接收者对应的消息队列中
5.广播接收者通过消息循环拿到此广播,并在onReceive中做出对应操作
特别注意:广播发送者和广播接收这都属于异步执行操作,发送者发送消息之后就不再关心有无接收者和何时接收广播
运用场景
什么情况下会用到广播?
广播相当于一个全局的喇叭,一处通知,全局通知,就比如当网络发生变化的时候,我们可以通过发送一条网络改变的广播,来通知网络变化,来提示用户。
项目实战(消息右上角小红点的显示和隐藏)
当有消息未读是显示小红点,但是我们有4个fragment,总不能每进入一次fragment时我们都请求一次接口吧,所以我这里用到的就是广播,在第一次进入时请求接口然后全局通知每个,当接收到这个广播改变小红点的显示隐藏,当将消息设为已读时也全局通知一下改变状态,如果你们有更好的解决办法,可以再评论区说下,小编也去试试!
广播注册方式( 静态注册、动态注册)
静态注册
1.创建一个类并继承BroadcastReceiver,系统会自动实现onReceive
2.系统自动在AndroidManifest.xml中创建receiver,创建intent-filter实现action android:name
3.发送/接收广播
注意:android在 8.0注册静态广播会接受不到,只需要在在Intent的时候添加setPackage(getPackageName())
这样的话就可以正常接收广播,也可以通过动态注册广播来实现通知
1.第一步创建MyBroadcastReceiver并且继承BroadcastReceiver
public class MyBroadcastReceiver extends BroadcastReceiver {
private static final String ACTION_BOOT = "android.intent.action.BOOT_COMPLETED";
@Override
public void onReceive(Context context, Intent intent) {
//处理收到广播的逻辑:
Toast.makeText(context, "广播来了", Toast.LENGTH_SHORT).show();
}
1-1 这里会自动在AndroidManifest.xml中创建receiver
<receiver android:name=".MyBroadcastReceiver">
<intent-filter >
<!--这里必须加intent-filter不然也接收不到-->
<action android:name="MyBroadcastReceiver" />
</intent-filter>
</receiver>
2.第二步发送静态注册广播
Intent intent = new Intent();
intent.putExtra("msg", "你呢1");
intent.setPackage(getPackageName());//8.0一下可以不用加这个也可以收到广播,但是8.0以后就需要加上这个不然收不到广播
sendBroadcast(intent);
3.这里主要是对receiver属性的一些认识
enabled 用于定义系统是否能够实例化这个广播 默认是true 可以实例化 false 不可以实例化
application和receiver中都有enabled都有这个属性 只有当这两个都设置为true 广播接收器才可以被启用
有任何一个设置为false,广播接收器都不能被实例化
exproted 用于设置广播接收器是否可以接收来自应用程序外部的消息
默认值是根据receiver中有无iintent-filter决定 如果有intent-filter 默认值为true否则为false
这个属性并不是唯一来判断接收外部消息的标识 还可以通过权限来限制能够给它发送消息的外部实体
icon 定义一个广播接收器的图标 这个属性必须包含图片定义的可绘制资源
如果没有设置icon 可以通过application中的icon的属性来代替
无论是receriver还是application中的icon都可以用来当作广播接收器的图标
label 用来给广播接收器来设定一个用户可读懂的文本标签 使用字符串即可
无论是receriver还是application中的label都可以用来当作广播接收器的文本标签
name 用广播接收器的实现类的类名来设置
用com.dongbo.model.MyBroadcastRecriver全包名或者.MyBroadcastRecriver都可以
这个没有默认值 必须被指定
一旦应用发布了 就不应该再改这个名字(除非exported设置为false 不接受外部实体)
permission 只有具有相应权限的广播发送者发送的权限才可以被此BraodcastReciver接收
当我们在开发过程中 希望发送一些广播来通知其他应用 但是又不希望一些敏感的广播被第三方接收到
这里就需要我们自己来定制特定的广播权限 谁可以接收我的广播 谁可以发送广播给我
process BroadcastReceiver所在的进程
默认为app的进程 但是可以自己设置进程
Android四大组件都可以通过process来设置自己的进程
大家可以自己去实践下,看看这些属性的效果。。
到这里静态注册广播就算结束了
动态注册(需要通过代码来实现注册)
这里主要就是实现了网络变化时,通过广播来提示用户
1.在oncreate中注册广播 在onDestory中注销广播
2.发送/接收广播
1.第一步创建broadcastReceiver并继承BroadcastReceiver(也可以通过创建匿名内部类来实现这里只是为了快速效果,大家以后可以根据自己的需求),并且实现onReceive,不用AndroidManifest.xml实现receiver
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isAvailable()) {
Toast.makeText(context, "网络可用", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "网络不可用", Toast.LENGTH_SHORT).show();
}
}
};
2.注册和注销广播
注册:
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(broadcastReceiver, intentFilter);
注销:
if (broadcastReceiver != null) {
unregisterReceiver(broadcastReceiver);
}
这样就可以实现变化来通知用户
两者区别
- 静态注册(常驻广播,不受任何组建的影响,即使应用退出了,如果有信息的广播还是会接收到,应用场景:时刻监听)
- 动态注册(非常驻广播,跟随组件的生命周期,退出应用就相当于广播结束,在结束之前必须移除广播接收器,应用场景:需要的时候才进行监听)
到此BroadcastReceiver的基础讲解就到此结束,下一篇我会找几个运用场景以及对自己项目中运用到的广播进行改善,更好的运用到项目中,还有实现不同应用之间的通信!
网友评论