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

news/2024/11/26 11:04:25/

参考资料:

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 androidxref.com/9.0.0_r3/s?refs=processNextBroadcastLocked&project=frameworks" rel="nofollow" title="processNextBroadcastLocked">processNextBroadcastLocked(boolean androidxref.com/9.0.0_r3/s?refs=fromMsg&project=frameworks" rel="nofollow" title="fromMsg">fromMsg, boolean androidxref.com/9.0.0_r3/s?refs=skipOomAdj&project=frameworks" rel="nofollow" title="skipOomAdj">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.ppmy.cn/news/1550044.html

相关文章

通信综合—8.通信网络安全

一、信息系统安全概述 1.信息系统的构成和分类 信息系统是将用于收集、处理、存储和传播信息的部件组织在一起而成的相关联的整体&#xff0c;般是由计算机硬件、网络和通信设备、计算机软件、信息资源和信息用户组成。它是以处理信息流为目的的人机一体化系统。信息系统主要…

蓝桥杯不知道叫什么题目

小蓝有一个整数&#xff0c;初始值为1&#xff0c;他可以花费一些代价对这个整数进行变换。 小蓝可以花贵1的代价将教数增加1。 小蓝可以花费3的代价将整数增加一个值,这个值是整数的数位中最大的那个(1到9) .小蓝可以花费10的代价将整数变为原来的2倍, 例如&#xff0c;如果整…

Linux文件编程(持续更新)

Linux系统提供了一系列自动化完成文件编程的API&#xff0c;如&#xff1a; 打开 open 读写 write/read 光标定位 lseek 关闭 close ——————————————————————————————————————————— mode 0600&#xff08;第一个0无意义&#…

MySQL基础知识大总结

一&#xff0c;介绍 数据库是什么&#xff0c;我们在学习其他编程语言的时候会使用数组呀&#xff0c;链表&#xff0c;二叉树等等一些数据结构来存储我们的数据&#xff0c;但是大家有没有发现我们一旦关闭程序&#xff0c;所有的数据都没有了&#xff0c;这在发行的软件来看是…

《硬件架构的艺术》笔记(六):处理字节顺序

介绍 本章主要介绍字节顺序的的基本规则。&#xff08;感觉偏软件了&#xff0c;不知道为啥那么会放进《硬件架构的艺术》这本书&#xff09;。 定义 字节顺序定义数据在计算机系统中的存储格式&#xff0c;描述存储器中的MSB和LSB的位置。对于数据始终以32位形式保存在存储器…

Spring 框架七大模块(Java EE 学习笔记03)

​ ​核心容器模块&#xff08;Core Container&#xff09; 核心容器模块在Spring的功能体系中起着支撑性作用&#xff0c;是其他模块的基石。核心容器层主要由Beans模块、Core模块、Contex模块和SpEL模块组成。 &#xff08;1&#xff09;Beans模块。它提供了BeanFactory类&…

spring boot jpa中 Hibernate 注解 @Immutable 的使用场景

入门示例 使用 spring boot jpa 来操作数据库的增删改查是非常方便的&#xff0c;定义完 model 之后&#xff0c;直接定义JPA 即可&#xff0c;后续操作就很丝滑了&#xff1a; Table(name "host_spec_price") Data Entity public class BudgetHost {IdGeneratedV…

后端开发详细学习框架与路线

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;后端开发 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 为帮助你合理安排时间&#xff0c;以下是结合上述学习内容的阶段划分与时间分配建议。时间安排灵活&a…