Android中广播分为两个个角色:广播发送者、广播接收者。是四大组件之一,是一个全局的监听器。
文章目录
一、作用
1、用于监听/接收应用发出的广播消息,并做出响应。
2、应用场景a,不同组件之间通信(包括应用内/不同应用之间) 与Android系统在特定情况下的通信。如当电话呼入时、网络可用时
3、多线程通信
二、原理描述
1、广播接收者通过Binder机制在AMS注册。
2、广播发送者通过Binder机制在AMS发送广播。
3、AMS(Activity Manager Service)根据广播发送者要求,在已注册列表中,寻找合适的广播接收者。寻找依据:IntentFilter/Permission
4、AMS将广播发送到合适的广播接收者相应的消息循环队列中
5、广播接收者通过消息循环拿到此广播,并回调onReceive()
广播发送者和广播接收者的执行都是异步的。
三、自定义广播接收者BroadcastReceiver
1、必须复写抽象方法onReceive()方法。
广播接收器接收到相应广播后,会自动回调onReceive()方法。
onReceive方法会涉及与其他组件之间的交互,发送Notification、启动service等
广播接收器运行在UI线程,onReceive方法不能执行耗时操作,会导致ANR。
2、代码实例mBroadcastReceiver
public class mBroadcastReceiver extends BroadcastReceiver {
//接收到广播后自动调用该方法
@Override
public void onReceive(Context context, Intent intent) {
//写入接收广播后的操作
}
}
四、广播接收器注册
注册分为静态注册和动态注册
1、静态注册
在AndroidManifest.xml通过,标签声明。
<receiver
<!--android:enabled=["true" | "false"]-->
==这个是属性用于指示该服务是否能够被实例化。如果设置为true,则能够被实例化,负责不能被实例化。默认为true==
//此broadcastReceiver能否接收其他App的发出的广播
//默认值是由receiver中有无intent-filter决定的:如果有intent-filter
,默认值为true,否则为false
<!--android:exported=["true" | "false"]-->
==这个是该服务是否能够被其他应用程序组件调用或去跟他交互。如果设置为true,则能够被交互或者调用,否则为false,只有同一个应用程序的组件或带有相同用户ID的应用程序才能启动或绑定该服务 这个默认值依赖与该服务所包含的过滤器。没有过滤器就是false,至少包含了一个过滤器,意味着该服务可以给外部的其他应用提供服务,默认为true==
android:icon="drawable resource"
android:label="string resource"
==这个是要显示给用户服务的名称。如果没有设置该属性,则会使用<application>元素中的label来替代==
//继承BroadcastReceiver子类的类名
android:name=".mBroadcastReceiver"
//具有相应权限的广播发送者发送的广播才能被此BroadcastReceiver所接收;
android:permission="string"
==这个是要启动或绑定服务的实体必须要使用的权限。==
//BroadcastReceiver运行所处的进程
//默认为app的进程,可以指定独立的进程
//注:Android四大基本组件都可以通过此属性指定自己的独立进程
android:process="string" >
//用于指定此广播接收器将接收的广播类型
//本示例中给出的是用于接收网络状态改变时发出的广播
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"
/>
</intent-filter>
</receiver>
2、注册的例子
<receiver
//此广播接收者类是mBroadcastReceiver
android:name=".mBroadcastReceiver" >
//用于接收网络状态改变时发出的广播
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CH
ANGE" />
</intent-filter>
</receiver>
这个是当App首次启动时,系统就会自动实例化mBroadcastReceiver类,并且开始去注册到系统中去。
3、动态注册
在代码中是通过调用Context的registerReceiver()方法进行动态注册BroadcastReceiver,
@Override
protected void onResume() {
super.onResume();
//实例化mBroadcastReceiver子类 & IntentFilter
mBroadcastReceiver mBroadcastReceiver = new mBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
//设置接收广播的类型
intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);
//调用Context的registerReceiver()方法进行动态注册
registerReceiver(mBroadcastReceiver, intentFilter);
}
//注册广播后,要在相应位置记得销毁广播
//即在onPause() 中unregisterReceiver(mBroadcastReceiver)
//当此Activity实例化时,会动态将MyBroadcastReceiver注册到系统中
//当此Activity销毁时,动态注册的MyBroadcastReceiver将不再接收到相应的广播。
@Override
protected void onPause() {
super.onPause();
//销毁在onResume()方法中的广播
unregisterReceiver(mBroadcastReceiver);
}
这个动态广播最好在Activity的onResume注册、onPause注销
原因是:对于动态广播,有注册就有注销,否则会导致内存泄露。
4、两种广播的区别
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-unZPysFI-1626436687170)(/Users/wuzhangxiao/Library/Application Support/typora-user-images/image-20210715201657841.png)]
五、广播的发送
1、广播的发送
广播是由意图(Intent)标示。广播发送者将此广播的意图通过sendBroadcast()方法发送出去。
2、广播的类型
1、普通广播(Normal Broadcast)
开发者自定义的intent的广播,使用方法是
Intent intent=new Intent();
//对应的BroadcastReceiver中intentFilter的action
intent.setAction(BPOADCAST_ACTION);
//发送广播
sendBroadcast(intent);
这个时候如果有被注册的广播接收者中注册时intentFilter的action与上述匹配,就会接收到广播,然后进行回调onReceiver
调用
<receiver
//此广播接收者类是mBroadcastReceiver
android:name=".mBroadcastReceiver" >
//用于接收网络状态改变时发出的广播
<intent-filter>
<action android:name="BROADCAST_ACTION" />
</intent-filter>
</receiver>
这个时候中的mBroadcastReceiver就可以开始去接收到消息了。
诺发送广播有相应的权限,那么广播接收者也需要相应的权限。
2、系统广播(System Broadcast)
Android手机中自带系统广播:只要涉及手机的基本操作(开机、网络状态变化、拍照等等),这个时候就会去发出相应的广播。每个特定的Intent—Filter(包括相应的action)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8VX6O4R5-1626436687171)(/Users/wuzhangxiao/Library/Application Support/typora-user-images/image-20210716100539509.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GKiEAnF8-1626436687173)(/Users/wuzhangxiao/Library/Application Support/typora-user-images/image-20210716101801948.png)]
这个时候如果需要,只需要在注册广播接收者时定义相关的action即可
3、有序广播(Ordered Broadcast)
这个是定义发送出去的广播接收者按照先后顺序接收。
有序是针对广播接收者而言
1、接收顺序规则
按照Priority属性值从大-小排序
Priority属性相同,动态注册的广播优先。
2、特点
接收广播按顺序接收
先接收到广播接收者可以对广播进行截断,后接收到广播接收者不再接收
先接收到广播接收者可以对广播进行修改,后接收到广播接收者将接收修改的。
发送方式:sendOrderedBroadcast(intent);
4、App应用内广播(Local Broadcast)
Android中的广播可以直接跨App直接通信(exported对于有intent-filter情况下默认值为true)
1、会遇到的问题:
其他App针对性发出与当前App intent-filter相匹配的广播,由此导致当前App不断接收广播并处理;
其他App注册与当前App一致的intent-filter用于接收广播,获取广播具体信息; 即会出现安全性 & 效率性的问题。
2、解决方案:
1、App应用内广播可以理解为局部广播,广播的发送者和接收者都是同一个App
2、相比于全局广播(普通广播),App应用内广播优势在安全性高和效率高。
3、使用方法
将全局广播设置成局部广播:
1、在注册时将exported属性设置为false,这个可以使非本App内部发出的此广播不被接收;
2、广播发送和接收,增设相应权限permission,可以进行验证
3、发送广播时指定广播接收器所在的包名,这个时候只会发送到此包中App有效的广播接收器中
通过intent.setPackage(packageName)指定报名
5粘性广播(Sticky Broadcast)
这个已经被废除。