【阅读笔记】Android广播的处理流程

关于Android的解析,有很多优质内容,看了后记录一下阅读笔记,也是一种有意义的事情,

今天就看看“那个写代码的”这位大佬关于广播的梳理,

https://blog.csdn.net/a572423926/category_11509429.html

https://blog.csdn.net/a572423926/article/details/121760258

广播的原理很清晰,类似一种观察者模式,控制中心把广播发送给注册者(观察者),但是android中的实现细节较多。

这里通过一个am命令发送受保护的广播,查看抛出的异常,看相关堆栈。

am broadcast -n com.example.test/.AppInstallReceiver -a android.intent.action.SCREEN_ON

am broadcast -n com.example.test/.AppInstallReceiver -a android.intent.action.SCREEN_ON
Broadcasting: Intent { act=android.intent.action.SCREEN_ON flg=0x400000 cmp=com.example.test/.AppInstallReceiver }Exception occurred while executing 'broadcast':
java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.intent.action.SCREEN_ON from pid=18179, uid=2000at com.android.server.am.ActivityManagerService.broadcastIntentLocked(ActivityManagerService.java:14369)at com.android.server.am.ActivityManagerService.broadcastIntentLocked(ActivityManagerService.java:14206)at com.android.server.am.ActivityManagerService.broadcastIntentWithFeature(ActivityManagerService.java:15092)at com.android.server.am.ActivityManagerShellCommand.runSendBroadcast(ActivityManagerShellCommand.java:806)at com.android.server.am.ActivityManagerShellCommand.onCommand(ActivityManagerShellCommand.java:221)at com.android.modules.utils.BasicShellCommandHandler.exec(BasicShellCommandHandler.java:97)at android.os.ShellCommand.exec(ShellCommand.java:38)at com.android.server.am.ActivityManagerService.onShellCommand(ActivityManagerService.java:9776)at android.os.Binder.shellCommand(Binder.java:1055)at android.os.Binder.onTransact(Binder.java:883)at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:4845)at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2833)at android.os.Binder.execTransactInternal(Binder.java:1291)at android.os.Binder.execTransact(Binder.java:1250)调用到ActivityManagerService.broadcastIntentLocked

app中发送广播后,会调用到ActivityManagerService.broadcastIntentLocked

在PMS中查询,有哪些接收者

这里可以把ResolveInfo打印出来进行查看接收者是否被筛选出来了,具体分析可查看原文。

然后,进行分发,

会调用到BroadcastQueue.java 的processNextBroadcast,有些广播接收不到,就是在这里面进行了屏蔽。

processNextBroadcast的代码设计不好,

对于并行广播,搞了个循环来一下子处理完成。

“processNextBroadcast 每次被调用,只能分发给 mOrderedBroadcasts 中一个广播的其中一个 Receiver,如果静态注册的应用未启动,还需要等待应用启动后再进行处理。”

/frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.javafinal void processNextBroadcast(boolean fromMsg) {synchronized(mService) {BroadcastRecord r;......// 这里的do-while只会从mOrderedBroadcasts中取出第一个BroadcastRecord进行后续的处理!do {......r = mOrderedBroadcasts.get(0);......} while (r == null);......final Object nextReceiver = r.receivers.get(recIdx); // 取出一个Receiver// 对动态注册receiver的处理,这里是分发有序广播if (nextReceiver instanceof BroadcastFilter) {......// 通过deliverToRegisteredReceiverLocked调用ActivityThread.scheduleRegisteredReceiver处理广播deliverToRegisteredReceiverLocked(r, filter, r.ordered, recIdx);......}// 开始对静态注册receiver的处理!!!ResolveInfo info = (ResolveInfo)nextReceiver;......// 如果应用已经启动,则直接分发广播给该应用,并返回if (app != null && app.thread != null && !app.killed) {try {app.addPackage(info.activityInfo.packageName,info.activityInfo.applicationInfo.versionCode, mService.mProcessStats);// 通过processCurBroadcastLocked -> ActivityThread.scheduleReceiver -> receiver.onReceive处理当前广播processCurBroadcastLocked(r, app);return;} catch (RemoteException e) {Slog.w(TAG, "Exception when sending broadcast to "+ r.curComponent, e);} catch (RuntimeException e) {Slog.wtf(TAG, "Failed sending broadcast to "+ r.curComponent + " with " + r.intent, e);......return;}}......// 如果应用未启动,则在这里启动应用进程,广播将在AMS启动完成后被调用处理if ((r.curApp=mService.startProcessLocked(targetProcess,info.activityInfo.applicationInfo, true,r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,"broadcast", r.curComponent,(r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false))== null) {Slog.w(TAG, "Unable to launch app "+ info.activityInfo.applicationInfo.packageName + "/"+ info.activityInfo.applicationInfo.uid + " for broadcast "+ r.intent + ": process is bad");......return;}// 将BroadcastRecord赋值为mPendingBroadcast,等待应用启动完成后处理mPendingBroadcast = r;mPendingBroadcastRecvIndex = recIdx;}
}

这里面

通过 deliverToRegisteredReceiverLocked 调用到 ActivityThread.scheduleRegisteredReceiver,处理动态注册的 receiver;通过 processCurBroadcastLocked,调用到 ActivityThread.scheduleReceiver,处理静态注册的 receiver

这样,就传送给app端了。

参考资料:https://blog.csdn.net/a572423926/article/details/121760258
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/a572423926/article/details/121760258

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/62832.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++boost::asio网络编程】有关异步读写api的笔记

异步读写api 异步写操作async_write_someasync_send 异步读操作async_read_someasync_receive 定义一个Session类&#xff0c;主要是为了服务端专门为客户端服务创建的管理类 class Session { public:Session(std::shared_ptr<asio::ip::tcp::socket> socket);void Conn…

Proteus8.17下载安装教程

Proteus是一款嵌入式系统仿真开发软件&#xff0c;实现了从原理图设计、单片机编程、系统仿真到PCB设计&#xff0c;真正实现了从概念到产品的完整设计&#xff0c;其处理器模型支持8051、HC11、PIC10/12/16/18/24/30/DsPIC33、AVR、ARM、8086和MSP430等&#xff0c;能够帮助用…

frp 内网穿透

文章目录 前言使用自己的服务器搭建frp 这里服务器是linux centos 7 宝塔&#xff0c;client是 windows10 https://github.com/fatedier/frp/releases/tag/v0.53.2 版本下载分客户端与服务端 一、frp是什么&#xff1f;二、使用步骤1.部署服务器端2.客户端 前言 使用自己的服务…

大数据-239 离线数仓 - 广告业务 测试 FlumeAgent 加载ODS、DWD层

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; Java篇开始了&#xff01; 目前开始更新 MyBatis&#xff0c;一起深入浅出&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff0…

基于 SpringBoot 开发在线家具商城:设计架构与实践流程

第3章 系统分析 用户的需求以及与本系统相似的在市场上存在的其它系统可以作为系统分析中参考的资料&#xff0c;分析人员可以根据这些信息确定出本系统具备的功能&#xff0c;分析出本系统具备的性能等内容。 3.1可行性分析 尽管系统是根据用户的要求进行制作&#xff0c;但是…

【Django-xadmin】

时间长不用,会忘的系列 1、Django-xadmin后台字段显示处理 主要是修改每个模块下adminx.py文件 代码解释&#xff1a;第1行控制表单字段显示第2行控制列表字段显示第3行控制搜索条件第4行控制过滤条件第5行支持单个或多个字段信息修改第6行列表分页&#xff0c;每页显示多少行…

【HM-React】02. React基础-下

React表单控制 受控绑定 概念&#xff1a;使用React组件的状态&#xff08;useState&#xff09;控制表单的状态 function App(){const [value, setValue] useState()return (<input type"text" value{value} onChange{e > setValue(e.target.value)}/>) …

朗迪锋亮相2024人因工程与智能系统交互国际会议

2024年11月28日至30日&#xff0c;2024人因工程与智能系统交互国际会议在深圳隆重举办。此次大会以推动我国人因工程学科发展为目标&#xff0c;致力于加强国际学术交流&#xff0c;深入探讨人工智能时代的智能系统交互&#xff0c;旨在培育新质生产力&#xff0c;助力经济社会…

基于Java Springboot房屋租赁App且微信小程序

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 微信…

【小白学机器学习42】进行多次抽样,样本的分布参数和总体的分布参数的关系

目录 1 进行多次抽样&#xff0c;样本的分布参数和总体的分布参数的关系 2 样本容量越大&#xff0c;多次抽样的样本的分布参数和总体的分布参数的关系 2.1 如果进行多次抽样&#xff0c;样本的均值将趋向总体的均值 2.2 换句话说&#xff1a;样本的均值将趋向总体的均值就…

Spring Web开发(请求)获取JOSN对象| 获取数据(Header)

大家好&#xff0c;我叫小帅今天我们来继续Spring Boot的内容。 文章目录 1. 获取JSON对象2. 获取URL中参数PathVariable3.上传⽂件RequestPart3. 获取Cookie/Session3.1 获取和设置Cookie3.1.1传统获取Cookie3.1.2简洁获取Cookie 3. 2 获取和存储Session3.2.1获取Session&…

CSS学习记录03

CSS背景 CSS 背景属性用于定义元素的背景效果。 CSS background-color background-color属性指定元素的背景色。 页面的背景色设置如下&#xff1a; body {background-color: lightblue; } 通过CSS&#xff0c;颜色通常由以下方式指定&#xff1a; 有效的颜色名称-比如“…

Matlab mex- setup报错—错误使用 mex,未检测到支持的编译器...

错误日志&#xff1a; 在使用mex编译时报错提示&#xff1a;错误使用 mex&#xff0c;未检测到支持的编译器。您可以安装免费提供的 MinGW-w64 C/C 编译器&#xff1b;请参阅安装 MinGW-w64 编译器。有关更多选项&#xff0c;请访问https://www.mathworks.com/support/compile…

STM32CUBEIDE FreeRTOS操作教程(十):interrupt on/off中断开关

STM32CUBEIDE FreeRTOS操作教程&#xff08;十&#xff09;&#xff1a;interrupt on/off中断开关 STM32CUBE开发环境集成了STM32 HAL库进行FreeRTOS配置和开发的组件&#xff0c;不需要用户自己进行FreeRTOS的移植。这里介绍最简化的用户操作类应用教程。以STM32F401RCT6开发…

Python学习38天

class Person:def __init__(self, name, age, job):self.name nameself.age ageself.job job# 重写函数返回属性def __str__(self):return f"{self.name}--{self.age}--{self.job}"# 冒泡排序法 def bubble_sort(my_list: list[Person]):"""冒泡排…

Python 调用 Umi-OCR API 批量识别图片/PDF文档数据

目录 一、需求分析 二、方案设计&#xff08;概要/详细&#xff09; 三、技术选型 四、OCR 测试 Demo 五、批量文件识别完整代码实现 六、总结 一、需求分析 市场部同事进行采购或给客户报价时&#xff0c;往往基于过往采购合同数据&#xff0c;给出现在采购或报价的金额…

【AI系统】AI 编译器基本架构

AI 编译器基本架构 在上一篇文章中将 AI 编译器的发展大致分为了 3 个阶段&#xff0c;分别为 1&#xff09;朴素编译器、2&#xff09;专用编译器以及 3&#xff09;通用编译器。 本文作为上一篇文章 AI 编译器架构的一个延续&#xff0c;着重讨论 AI 编译器的通用架构。首先…

java版工程项目管理系统源码:Spring Cloud与前后端分离的完美结合

在现代化的工程项目管理中&#xff0c;一套功能全面、操作便捷的系统至关重要。本文将介绍一个基于Spring Cloud和Spring Boot技术的Java版工程项目管理系统&#xff0c;结合Vue和ElementUI实现前后端分离。该系统涵盖了项目管理、合同管理、预警管理、竣工管理、质量管理等多个…

近几年,GIS专业的五类就业方向!

近二十几年来&#xff0c;地理信息科学毕业生的就业方向在不断发生变化。 早期的地理信息科学技术主要应用于政府部门&#xff0c;因此学生就业主要在高校、交通运输、规划勘测设计、国土、矿业、水利电力、通讯、农林、城市建设、旅游等国家政府部门或事业单位。 随着地理信…

css选择当前元素前面的一个元素

选择text-danger前面的ant-divider: .ant-divider:has( .text-danger) {display: none; }