参考资料:
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
代码细节很多,还是要仔细查看,还是那句话,"只在此山中,云深不知处"