【Android】静态广播接收不到问题分析思路

参考资料:

Android 静态广播注册流程(广播2)-CSDN博客

Android广播发送流程(广播3)_android 发送广播-CSDN博客

https://zhuanlan.zhihu.com/p/347227068

在Android中,静态广播如果静态广播不能接收,我们可以从整个流程中去分析,是否注册成功了,或者是在发送过程中出现了问题,参考资料中的流程可以去看几遍。

在dump信息中,可以通过查看receiver的信息,

Receiver Resolver Table:

Non-Data Actions:

      android.intent.action.PACKAGE_REMOVED:

        88141ab com.example.test/.AppInstallReceiver

这里一般不会出现问题,

dumpsys activity broadcast-stats 可以看到一些信息。

如果出现类似下面的log

11-24 20:43:28.929  1748  3469 W BroadcastQueue: Background execution not allowed: receiving Intent { act=android.intent.action.PACKAGE_REPLACED dat=package: flg=0x4000010 (has extras) } to com.smile.gifmaker/com.yxcorp.gifshow.ad.detail.AppInstalledReceiver

这一种也比较直观,查看BroadcastQueue.java可以找到对应的代码,

final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj)里面

可以参考

https://zhuanlan.zhihu.com/p/347227068

如果没有直观的BroadcastQueue 的log,还是要看看广播发送流程,

参考 Android广播发送流程(广播3)_android 发送广播-CSDN博客

    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,int callingUid, int[] users, int[] broadcastAllowList) {// TODO: come back and remove this assumption to triage all broadcastsint pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;List<ResolveInfo> receivers = null;try {HashSet<ComponentName> singleUserReceivers = null;boolean scannedFirstReceivers = false;for (int user : users) {// Skip users that have Shell restrictions//如果调用者是shell,而且该user不允许shell调试,则跳过if (callingUid == SHELL_UID&& mUserController.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {continue;}//静态广播通过PMS去查询接收者List<ResolveInfo> newReceivers = AppGlobals.getPackageManager().queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();if (user != UserHandle.USER_SYSTEM && newReceivers != null) {// If this is not the system user, we need to check for// any receivers that should be filtered out.for (int i=0; i<newReceivers.size(); i++) {ResolveInfo ri = newReceivers.get(i);//如果取出来的ResolveInfo包含了只允许系统接收的flag(FLAG_SYSTEM_USER_ONLY),//则从筛选出来的列表中移除这个接收者if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {newReceivers.remove(i);i--;}}}//如果到目前为止newReceivers(ResolveInfo列表)为null或者空的if (newReceivers != null && newReceivers.size() == 0) {newReceivers = null;}if (receivers == null) {//如果receivers(最后返回的结果)为null,则先将newReceivers赋值给receiversreceivers = newReceivers;} else if (newReceivers != null) {// We need to concatenate the additional receivers// found with what we have do far.  This would be easy,// but we also need to de-dup any receivers that are// singleUser.//scannedFirstReceivers默认是fasle,也就是第一次跑到这段代码会进来,只进来一次//receivers此时已经赋值过一次,这里是users第二次和以上循环才可能会进来if (!scannedFirstReceivers) {// Collect any single user receivers we had already retrieved.scannedFirstReceivers = true;// 遍历之前的receivers(这里receivers没有判空逻辑,只看这段逻辑不太严谨,// 没有出错是由于newReceivers有判空)for (int i=0; i<receivers.size(); i++) {ResolveInfo ri = receivers.get(i);//如果接收者包含FLAG_SINGLE_USER的flagif ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {ComponentName cn = new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name);if (singleUserReceivers == null) {singleUserReceivers = new HashSet<ComponentName>();}//则把这类组件add到singleUserReceivers中singleUserReceivers.add(cn);}}}// Add the new results to the existing results, tracking// and de-dupping single user receivers.// 遍历新的users中获取的newReceiversfor (int i=0; i<newReceivers.size(); i++) {ResolveInfo ri = newReceivers.get(i);//如果也是带有FLAG_SINGLE_USER的flag,只发送给单个userif ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {ComponentName cn = new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name);if (singleUserReceivers == null) {singleUserReceivers = new HashSet<ComponentName>();}//如果之前还没有添加过,才进行receivers添加if (!singleUserReceivers.contains(cn)) {//而且将单个用户接受者ComponentName cn添加到ComponentName中singleUserReceivers.add(cn);receivers.add(ri);}} else {//其它情况则直接加入该接收者到receiversreceivers.add(ri);}}}}} catch (RemoteException ex) {// pm is in same process, this will never happen.}//如果带有broadcastAllowList,允许接收该广播uid的列表if (receivers != null && broadcastAllowList != null) {for (int i = receivers.size() - 1; i >= 0; i--) {final int receiverAppId = UserHandle.getAppId(receivers.get(i).activityInfo.applicationInfo.uid);//接受者的uid如果是app进程,而且不在允许接收该广播uid的列表,则移除查询到的接收者if (receiverAppId >= Process.FIRST_APPLICATION_UID&& Arrays.binarySearch(broadcastAllowList, receiverAppId) < 0) {receivers.remove(i);}}}//返回接受者return receivers;}

这里看看

ResolveInfo

代码细节很多,还是要仔细查看,还是那句话,"只在此山中,云深不知处"

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

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

相关文章

2024 APMCM亚太数学建模C题 - 宠物行业及相关产业的发展分析和策略(详细解题思路)

在当下&#xff0c; 日益发展的时代&#xff0c;宠物的数量应该均为稳步上升&#xff0c;在美国出现了下降的趋势&#xff0c; 中国 2019-2020 年也下降&#xff0c;这部分变化可能与疫情相关。需要对该部分进行必要的解释说明。 问题 1: 基于附件 1 中的数据及您的团队收集的额…

Git简单介绍

一、 Git介绍与安装 1.1 Git简介 Git是一个开源的分布式版本控制系统&#xff0c;可以有效、高速地处理从很小到非常大的项目版本管理。 1.2集中式(SVN&#xff09; VS 分布式(git) 集中式版本控制系统&#xff0c;版本库是集中存放在中央服务器的&#xff0c;工作时要先从中央…

CSS之3D转换

三维坐标系 三维坐标系其实就是指立体空间&#xff0c;立体空间是由3个轴共同组成的。 x轴:水平向右注意:x右边是正值&#xff0c;左边是负值 y轴:垂直向下注意:y下面是正值&#xff0c;上面是负值 z轴:垂直屏幕注意:往外面是正值&#xff0c;往里面是负值 3D移动 translat…

kafka生产者和消费者命令的使用

kafka-console-producer.sh 生产数据 # 发送信息 指定topic即可 kafka-console-producer.sh \ --bootstrap-server bigdata01:9092 \ --topic topicA # 主题# 进程 29124 ConsoleProducer kafka-console-consumer.sh 消费数据 # 消费数据 kafka-console-consumer.sh \ --boo…

基于Springboot的心灵治愈交流平台系统的设计与实现

基于Springboot的心灵治愈交流平台系统 介绍 基于Springboot的心灵治愈交流平台系统&#xff0c;后端框架使用Springboot和mybatis&#xff0c;前端框架使用Vuehrml&#xff0c;数据库使用mysql&#xff0c;使用B/S架构实现前台用户系统和后台管理员系统&#xff0c;和不同级别…

【人工智能】Python常用库-Scikit-learn常用方法教程

Scikit-learn 是一个功能强大的机器学习库&#xff0c;支持数据预处理、分类、回归、聚类、降维等功能&#xff0c;广泛用于模型开发与评估。以下是 Scikit-learn 的常用方法及详细说明。 1. 安装与导入 安装 Scikit-learn&#xff1a; pip install scikit-learn导入基本模块…

Tcon技术和Tconless技术介绍

文章目录 TCON技术&#xff08;传统时序控制器&#xff09;定义&#xff1a;主要功能&#xff1a;优点&#xff1a;缺点&#xff1a; TCONless技术&#xff08;无独立时序控制器&#xff09;定义&#xff1a;工作原理&#xff1a;优点&#xff1a;缺点&#xff1a; TCON与TCONl…

计算机基础(下)

内存管理 内存管理主要做了什么&#xff1f; 操作系统的内存管理非常重要&#xff0c;主要负责下面这些事情&#xff1a; 内存的分配与回收&#xff1a;对进程所需的内存进行分配和释放&#xff0c;malloc 函数&#xff1a;申请内存&#xff0c;free 函数&#xff1a;释放内存…

【青牛科技】TS223 单触摸键检测IC

概 述 &#xff1a; TS223是 触 摸 键 检 测 IC&#xff0c; 提 供 1个 触 摸 键 。 触 摸 检 测 IC是 为 了用 可 变 面 积 的 键 取 代 传 统 的 按 钮 键 而 设 计 的 。低 功 耗 和 宽 工 作 电压是 触 摸 键 的 DC和 AC特 点 。TS223采 用 SSOP16、 SOT23-6的 封 装 形 式…

CUDA补充笔记

文章目录 一、不同核函数前缀二、指定kernel要执行的线程数量三、线程需要两个内置坐标变量来唯一标识线程四、不是blocksize越大越好&#xff0c;上限一般是1024个blocksize 一、不同核函数前缀 二、指定kernel要执行的线程数量 总共需要线程数是&#xff1a; 1 * N N个线程…

“华为杯”研究生数学建模比赛历年赛题汇总(2004-2024)

文章目录 赛题链接历年赛题2004年赛题2005年赛题2006年赛题2007年赛题2008年赛题2009年赛题2010年赛题2011年赛题2012年赛题2013年赛题2014年赛题2015年赛题2016年赛题2017年赛题2018年赛题2019年赛题2020年赛题2020年赛题2021年赛题2022年赛题2023年赛题2024年赛题 赛题链接 部…

Python学习指南 + 谷歌浏览器如何安装插件

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a; Python 目录 前言 Python 官方文档的使用 谷歌浏览器中如何安装插件 前言 在学习Python时&#xff0c;我们可能会出现这样的困惑&#x…

java写一个石头剪刀布小游戏

石头剪刀布是一款经典的手势游戏,通常由两人参与,玩法简单且充满趣味。玩家通过出示手势代表“石头”、“剪刀”或“布”,并根据规则比较手势决定胜负。它广泛用于休闲娱乐、决策或解压活动。 一、功能简介 用户与计算机对战。 用户输入选择:石头、剪刀或布。 计算机随机生…

docker如何安装redis

第一步 如果未指定redis&#xff0c;则安装的是最新版的 docker pull redis 创建一个目录 mkdir /usr/local/docker/redis 然后直接可以下载redis&#xff0c;这是方式确实不怎么好&#xff0c;应该找在官网上找对应的redis配置文件 wget http://download.redis.io/redis-stab…

【作业九】RNN-SRN-Seq2Seq

点击查看作业内容 目录 1 实现SRN &#xff08;1&#xff09;使用numpy实现 &#xff08;2&#xff09;在&#xff08;1&#xff09;的基础上&#xff0c;增加激活函数tanh &#xff08;3&#xff09;使用nn.RNNCell实现 &#xff08;4&#xff09;使用nn.RNN实现 2 使用R…

利用Docker容器技术部署发布web应用程序

Docker是什么&#xff1f; docker 是一个开源的应用容器引擎&#xff0c;可以帮助开发者打包应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何流行的Linux机器上&#xff0c;也可以实现虚拟化&#xff0c;容器是完全使用沙箱机制&#xff0c;相互之间不会有任何…

【AI学习】Mamba学习(十八):S6的硬件感知设计

上一篇Mamba的文章提到&#xff0c;S6 models这个名称的由来是&#xff1a;S4 models with a selection mechanism and computed with a scan。 所以&#xff0c;S6模型首先是选择机制&#xff1a;先前模型的一个关键限制对选择性复制和归纳等重要合成任务不够适用&#xff0c…

Bug Fix 20241122:缺少lib文件错误

今天有朋友提醒才突然发现 gitee 上传的代码存在两个很严重&#xff0c;同时也很低级的错误。 因为gitee的默认设置不允许二进制文件的提交&#xff0c; 所以PH47框架下的库文件&#xff08;各逻辑层的库文件&#xff09;&#xff0c;以及Stm32Cube驱动的库文件都没上传到Gi…

实现Excel文件和其他文件导出为压缩包,并导入

导出 后端&#xff1a; PostMapping("/exportExcelData")public void exportExcelData(HttpServletRequest request, HttpServletResponse response, RequestBody ResData resData) throws IOException {List<Long> menuIds resData.getMenuIds();List<Co…

4.4 JMeter 请求参数类型详解

欢迎大家订阅【软件测试】 专栏&#xff0c;开启你的软件测试学习之旅&#xff01; 文章目录 前言1 参数&#xff08;键值对形式&#xff09;2 消息体数据&#xff08;JSON/XML 格式&#xff09;3 文件上传 前言 在使用 JMeter 进行接口测试时&#xff0c;常见的请求参数类型主…