Android 为什么动态广播接收器比静态广播接收器要接受的早

如果,在短信拦截的软件中,程序员们就发现了这个问题。 同一优先级的广播接收器,动态的要比静态注册的早。

 

动态注册:即由代码注册的广播接收器

静态注册:即在 AndroidManifest.xml 中注册的广播接收器

 

优先级: 当广播为有序发送的时候,要按这个排序并顺序发送。

 

sendBroadcast 发送的是无序广播。

sendOrderedBroadcast 发送的是有序广播。

 

好了,现在寻找问题原因,在找原因前肯定有这样的想法,一个有序队列,既然允许有相同的优先级存在,那么在同优先级内要不然有排序子因素,要不基就是按照某种操作可能影响顺序。后者可能性很大。

 

打开源码,顺着 动态注册广播接受器 找,最后是 ActivityManagerService.java 这个文件找到了 registerReceiver 的实现。

同地也看到,存储的广播接收器列表是 HashMap mRegisteredReceivers 这个变理。

 里面有一段代码为:

  1. ReceiverList rl  
  2.     = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());  
  3. if (rl == null) {  
  4.     rl = new ReceiverList(this, callerApp,  
  5.             Binder.getCallingPid(),  
  6.             Binder.getCallingUid(), receiver);  
  7.     if (rl.app != null) {  
  8.         rl.app.receivers.add(rl);  
  9.     } else {  
  10.         try {  
  11.             receiver.asBinder().linkToDeath(rl, 0);  
  12.         } catch (RemoteException e) {  
  13.             return sticky;  
  14.         }  
  15.         rl.linkedToDeath = true;  
  16.     }  
  17.     mRegisteredReceivers.put(receiver.asBinder(), rl);  
  18. }  

在里面查找有没有这个 Receiver , 如果没有 put 进去。

 

看到这里貌似没有对广播的顺序做处理。是不是有别的地方做排序呢,找找成员变理,发现一个可疑的变量:

final ArrayList<BroadcastRecord> mOrderedBroadcasts

没错,感觉就应该是它了。

 

找找对它的操作,只有一处 mOrderedBroadcasts.set ,把代码摘录一下:

 

 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
                    callerPackage, callingPid, callingUid, requiredPermission,
                    receivers, resultTo, resultCode, resultData, map, ordered,
                    sticky, false);

 

mOrderedBroadcasts.set(i, r);

在这里放入了一个 BroadcastRecord 对像,而这个对像中主要的东西其实是 receivers

向上跟踪

  1. int NT = receivers != null ? receivers.size() : 0;  
  2. int it = 0;  
  3. ResolveInfo curt = null;  
  4. BroadcastFilter curr = null;  
  5. while (it < NT && ir < NR) {  
  6.     if (curt == null) {  
  7.         curt = (ResolveInfo)receivers.get(it);  
  8.     }  
  9.     if (curr == null) {  
  10.         curr = registeredReceivers.get(ir);  
  11.     }  
  12.     if (curr.getPriority() >= curt.priority) {  
  13.         // Insert this broadcast record into the final list.  
  14.         receivers.add(it, curr);  
  15.         ir++;  
  16.         curr = null;  
  17.         it++;  
  18.         NT++;  
  19.     } else {  
  20.         // Skip to the next ResolveInfo in the final list.  
  21.         it++;  
  22.         curt = null;  
  23.     }  
  24. }  

 发现了一段 对 receivers 排序的代码,并且判断也是 priority 的值,用的是 >=  方式

 感觉的找到了地方,但是对 Activity Manager Service 这个模块却更加的不懂了,以后有机会一定要分析一下这块是怎样设计的,才能确定本文的问题所在。

暂时记录,以后分析!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值