IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 【Android基础组件】BroadCast——广播三两事 -> 正文阅读

[移动开发]【Android基础组件】BroadCast——广播三两事

【Android基础组件】BroadCast——广播三两事

本文介绍了Android四大组件之一的广播的相关基础理论知识,想了解更多可参阅安卓官方文档或技术书籍。

什么是广播?

一般来说,广播可作为跨应用和普通用户流之外的消息传递系统。Android 应用与 Android 系统和其他 Android 应用之间可以相互收发广播消息,这与发布-订阅设计模式相似。这些广播会在所关注的事件发生时发送。应用也可以注册接收特定的广播。广播发出后,系统会自动将广播传送给同意接收这种广播的应用。

举栗时间
  • Android 系统会在发生各种系统事件时发送广播——如系统启动或设备开始充电时。
  • 应用可以发送自定义广播来通知其他应用它们可能感兴趣的事件——如一些新数据已下载。

有哪些广播?

本地广播与全局广播

  • 本地广播,只能够在应用程序的内部进行传递 ,并且相应广播接收器也只能接收来自应用程序发出的广播。
  • 全局广播便是能在应用之间进行传递的广播。相比之下,本地广播的的效率更高(无需进行进程间通信),而且您无需担心其他应用在收发您的广播时带来的任何安全问题。

标准广播与有序广播

  • 标准广播是一种完全异步执行的广播,广播发出后所有的BroadcastReceiver几乎会在同一时刻收到这条广播消息。这意味着该广播的效率比较高,但无法被截断。
  • 有序广播则是一种同步执行的广播,广播发出后,同一时间只有一个接收器会收到广播消息,在执行完onReceive方法后,广播才会继续传递。这意味着此时的接收器是有先后顺序的,并且在前面收到广播的接收器还可以对正在传递的广播进行截断(调用abortBroadcast方法)。接收器的运行顺序可以通过匹配的 intent-filter 的 android:priority 属性来控制;具有相同优先级的接收器将按随机顺序运行。

隐式广播与显式广播

  • 隐式广播:未指定发送给哪个应用程序的广播。注意,在Android 8.0之后的系统中,静态注册的BroadcastReceiver是无法接受除少数特殊的系统广播之外的隐式广播的。
  • 显式广播:经由setPackage()方法指定了目标程序的广播。

系统广播

系统广播指的是系统在发生各种系统事件时(如系统进入和退出飞行模式时)自动发送的广播。

广播怎么用?

广播的使用主要包括以下几个步骤:

  1. 编写广播,实现onReceive方法中的逻辑
  2. 在APP中对所需接收的广播进行注册
  3. 在某处发送广播
    sendOrderedBroadcast(Intent, String);//发送有序广播。
    sendBroadcast(Intent); //发送标准广播。
    LocalBroadcastManager.sendBroadcast(); //发送本地广播
    
  4. 在不再需要该广播时取消注册

怎么注册广播?

  • 静态注册:清单声明的接收器(系统将在广播发出后启动应用)
    系统软件包管理器会在应用安装时注册接收器。然后,该接收器会成为应用的一个独立入口点,这意味着如果应用当前未运行,系统可以启动应用并发送广播。
  • 动态注册:代码中调用registerReceiver(BroadcastReceiver, IntentFilter)注册的接收器
    如注册的是本地广播,请调用 LocalBroadcastManager.registerReceiver(BroadcastReceiver, IntentFilter)。
    注意:需要停止接收广播时,需调用unregisterReceiver(BroadcastRecveiver),特别是在不再需要接收器或上下文不再有效时,务必取消注册。请注意注册和注销接收器的位置,比方说,如果您使用 Activity 上下文在 onCreate(Bundle) 中注册接收器,则应在 onDestroy() 中注销,以防接收器从 Activity 上下文中泄露出去。如果您在 onResume() 中注册接收器,则应在 onPause() 中注销,以防多次注册接收器(如果您不想在暂停时接收广播,这样可以减少不必要的系统开销)。请勿在 onSaveInstanceState(Bundle) 中注销,因为如果用户在历史记录堆栈中后退,则不会调用此方法。

接收器的工作时间

接收器的工作时间与注册的上下文有关,只要上下文有效,接收器便能持续工作。

举栗时间
  • 如Activity中创建的接收器,只要Activity未被销毁,接收器便能收到广播。
  • 在应用上下文中注册的接收器,只要应用在运行,便可以收到广播。

使用时需要注意什么?

不可在onReceive方法中启动长时间运行的后台线程

当 BroadcastReceiver 在其 BroadcastReceiver.onReceive() 方法中接收到一个 Intent 时,它会启动一个线程,然后从该函数返回。一旦返回,则系统会认为 BroadcastReceiver 不再处于活动状态,因此不再需要其托管进程(除非其中有其他应用组件处于活动状态)。因此,系统可能会随时终止进程以回收内存,这样会终止在进程中运行的衍生线程
如要执行长时间运行的工作:

  • 在接收器的 onReceive() 方法中调用 goAsync(),并将 BroadcastReceiver.PendingResult传递给后台线程。这样,在从 onReceive()返回后,广播仍可保持活跃状态。不过,即使采用这种方法,系统仍希望您非常快速地完成广播(在 10秒以内)。为避免影响主线程,它允许您将工作移到另一个线程。
  • 使用 JobScheduler 调度作业,这样系统就知道进程中还有处于活动状态的任务正在进行中。
如果您不需要向应用以外的组件发送广播,就使用LocalBroadcastManager 来收发本地广播。

LocalBroadcastManager 效率更高(无需进行进程间通信),并且您无需考虑其他应用在收发您的广播时带来的任何安全问题。本地广播可在您的应用中作为通用的发布/订阅事件总线,而不会产生任何系统级广播开销。

优先使用动态注册而不是静态注册

如果有许多应用在其清单中注册接收相同的广播,可能会导致系统启动大量应用,从而对设备性能和用户体验造成严重影响。有时,Android 系统本身会强制使用动态注册的接收器。例如,CONNECTIVITY_ACTION 广播只会传送给动态注册的接收器。

请勿使用隐式 intent 广播敏感信息

任何注册接收广播的应用都可以读取这些信息。您可以通过以下三种方式控制哪些应用可以接收您的广播:

  • 可以在发送广播时指定权限。
  • 在 Android 4.0 及更高版本中,可以在发送广播时使用 setPackage(String)指定软件包。系统会将广播限定到与该软件包匹配的一组应用。
  • 可以使用 LocalBroadcastManager 发送本地广播。
当您注册接收器时,任何应用都可以向您应用的接收器发送潜在的恶意广播

您可以通过以下三种方式限制您的应用可以接收的广播:

  • 可以在注册广播接收器时指定权限。
  • 对于静态注册的接收器,您可以在清单中将 android:exported 属性设置为“false”。这样一来,接收器就不会接收来自应用外部的广播。
  • 可以使用 LocalBroadcastManager 限制您的应用只接收本地广播。
广播操作的命名空间是全局性的

请确保在您自己的命名空间中编写操作名称和其他字符串,否则可能会无意中与其他应用发生冲突。

请勿从广播接收器启动 Activity,否则会影响用户体验,尤其是有多个接收器时

相反,可以考虑显示通知。

拓展——发布/订阅模式与观察者模式区别

笔者在初次接触广播时误以为广播使用的是观察者模式,实则不然,而二者最大的区别在于调度的地方不同,观察者模式是由具体目标调度的,而发布/订阅模式是统一由调度中心调度的。
文末放上发布/订阅模式与观察者模式的对比博客,有疑惑的可了解:【设计模式(三):观察者模式与发布/订阅模式区别】https://www.cnblogs.com/lovesong/p/5272752.html

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-08-19 12:09:56  更:2021-08-19 12:11:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 9:41:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码