BroadcastReceiver

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)

这个已经被废除。

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值