Android学习路线_入门篇(六)四大组件之BroadcastReceiver

Android应用开发中核心的四大组件是整体应用的骨架,利用好四大组件才能搭建出一个合理高效的APP。我们要了解的第三个组件是BroadcastReceiver,它是应用中进行消息通信的一大方式,支持的场景广泛多样。

本文已收录至☞Android学习路线_梳理
上一篇☞Android学习路线_入门篇(五)Service的生命周期与如何保活
下一篇☞Android学习路线_入门篇(七)四大组件之ContentProvider

1. 广播

在介绍BroadcastReceiver之前,我们先要简单了解一下Android的广播机制。

1.1 简要机制流程

广播机制的原理参考观察者模式,基于消息的发布/订阅事件模型,将广播的发送者和接收者极大程度上解耦,方便集成,更易扩展。具体实现流程要点粗略概括如下:

  1. 广播接收者BroadcastReceiver通过Binder机制向AMS(Activity Manager Service)进行注册;

  2. 广播发送者通过binder机制向AMS发送广播;

  3. AMS查找符合相应条件(IntentFilter/Permission等)的BroadcastReceiver,将广播发送到BroadcastReceiver相应的消息循环队列中;

  4. 消息循环执行拿到此广播,回调BroadcastReceiver中的onReceive()方法。

广播发送者和广播接收者分别属于观察者模式中的消息发布和订阅两端,AMS属于中间的处理中心。广播发送者和广播接收者的执行是异步的,发出去的广播不会关心有无接收者接收,也不确定接收者到底是何时才能接收到。

表面上看广播作为Android广播机制中的实体,实际上这一实体本身是并不是以所谓的“广播”对象存在的,而是以“意图”Intent去表示。

1.2 广播的类型

  1. Normal Broadcast:普通广播
    普通广播会被注册了的相应的intent-filter匹配接收,且顺序是无序的。如果发送广播时有相应的权限要求,BroadCastReceiver如果想要接收此广播,也需要有相应的权限。具体可以使用的方法有:

    1. sendBroadcast(intent)
    2. sendBroadcast(intent, receiverPermission)
    3. sendBroadcastAsUser(intent, userHandler)
    4. sendBroadcastAsUser(intent, userHandler,receiverPermission)
  2. System Broadcast: 系统广播
    Android系统中内置了多个系统广播,在系统内部当特定事件发生时,由系统自动发出。如:开启启动,网络状态改变,拍照,屏幕关闭与开启,电量不足等等。每个系统广播都具有特定的action,系统广播发出后,将被相应的BroadcastReceiver接收。常见的的系统广播action如下:

    Action描述
    android.intent.action.BATTERY_CHANGED持久的广播,包含电池的充电状态,级别和其他信息。
    android.intent.action.BATTERY_LOW标识设备的低电量条件。
    android.intent.action.BATTERY_OKAY标识电池在电量低之后,现在已经好了。
    android.intent.action.BOOT_COMPLETED在系统完成启动后广播一次。
    android.intent.action.BUG_REPORT显示报告bug的活动。
    android.intent.action.CALL执行呼叫数据指定的某人。
    android.intent.action.CALL_BUTTON用户点击"呼叫"按钮打开拨号器或者其他拨号的合适界面。
    android.intent.action.DATE_CHANGED日期发生改变。
    android.intent.action.REBOOT设备重启。
  3. Ordered broadcast:有序广播
    有序广播的有序广播中的“有序”是针对广播接收者而言的,指的是发送出去的广播被BroadcastReceiver按照先后循序接收。

    BroadcastReceiver按照priority属性值从大到小排序,对于具有相同的priority的动态广播和静态广播,动态广播会排在前面。

    先接收的BroadcastReceiver可以对此有序广播进行截断,使后面的BroadcastReceiver不再接收到此广播,也可以对广播进行修改。

    有序广播的定义过程与普通广播无异,只是其的主要发送方式变为:sendOrderedBroadcast(intent, receiverPermission, ...)

  4. Sticky Broadcast:粘性广播
    在 android 5.0/api 21中deprecated,不再推荐使用,相应的还有粘性有序广播,同样已经deprecated。既然已经deprecated,此处不再多做总结。

  5. Local Broadcast:App应用内广播
    App应用内广播可以理解成一种局部广播的形式,广播的发送者和接收者都同属于一个App。除了实际的业务需求之外,同时还考虑到了广播机制中的安全性和效率问题,App应用内广播具备更高的安全性和更高的效率。

    为此,Android v4兼容包中给出了封装好的LocalBroadcastManager类,用于统一处理App应用内的广播问题,使用方式上与通常的全局广播几乎相同,只是注册/取消注册广播接收器和发送广播时将主调context变成了LocalBroadcastManager的单一实例。

2. BroadcastReceiver(广播接收器)

相信了解了广播机制的你肯定迫不及待想要看看广播的效果了吧,那么我们就赶紧看看BroadcastReceiver是怎么工作的吧~

2.1 注册BroadcastReceiver

2.1.1 静态注册

静态注册方式和之前注册Activity以及Service是一致的,即在AndroidManifest中注册,关键标签是<receiver>,通过<intent-filter>标签配合<action>标签对Intent进行过滤。我们先接收一个底电量的广播试试,详细代码如下:

<receiver android:name=".MyReceiver">
   <intent-filter>
      <action android:name="android.intent.action.BATTERY_LOW">
      </action>
   </intent-filter>
</receiver>

2.1.2 动态注册

与Activity和Service不同的是,BroadcastReceiver除了静态注册之外还可以在Context中进行动态注册。特别是自Android 8.0/api 26开始限制静态注册的方式,静态注册的BroadcastReceiver将无法收到隐式广播而只能接收指定了包名的显示广播,如果是动态注册的BroadcastReceiver则无任何限制。

动态注册时,无须在AndroidManifest中注册<receiver>组件,直接在代码中通过调用Context的registerReceiver()方法,可以在程序中动态注册BroadcastReceiver,要记得在Context销毁之前调用unregisterReceiver()方法注销BroadcastReceiver。

var mBroadcastReceiver: MyBroadcastReceiver? = null

override void onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    mBroadcastReceiver = MyBroadcastReceiver()
    val intentFilter = IntentFilter()
    intentFilter.addAction("android.intent.action.BATTERY_LOW")
    registerReceiver(mBroadcastReceiver, intentFilter)
}

override void onDestroy() {
    super.onDestroy()
    unregisterReceiver(mBroadcastReceiver)
}

2.2 创建类文件

BroadcastReceiver的类文件比较简单,只需要创建一个MyBroadcastReceiver类,继承BroadcastReceiver,再实现onReceive()方法,示例代码如下:

class MyBroadcastReceiver: BroadcastReceiver() {

    override onReceive(context: Context, intent: Intent) {
    	Toast.makeText(context, "收到广播", Toast.LENGTH_SHORT).show()
    }
}

onReceive()方法中可以拿到一个Context对象和一个Intent对象,通过Context对象我们可以执行一些依赖上下文的操作,而Intent对象里则有广播携带的一些额外数据。

完毕

今天的分享就到这里,文章多有不足,各位小伙伴有什么想法可以直接评论或是私信,要是对你有所帮助就给我一个赞吧,喜欢我的小伙伴可以关注我哦~

本文已收录至☞Android学习路线_梳理
上一篇☞Android学习路线_入门篇(五)Service的生命周期与如何保活
下一篇☞Android学习路线_入门篇(七)四大组件之ContentProvider

支持我的小伙伴们可以微信搜索“Android思维库”,或者微信扫描下方二维码,关注我的公众号,每天都会推送新知识~

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值