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

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

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

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

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

sendBroadcast 发送的是无序广播。

sendOrderedBroadcast 发送的是有序广播。

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

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

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

里面有一段代码为:

ReceiverList rl       = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());   if (rl == null) {       rl = new ReceiverList(this, callerApp,               Binder.getCallingPid(),               Binder.getCallingUid(), receiver);       if (rl.app != null) {           rl.app.receivers.add(rl);       } else {           try {               receiver.asBinder().linkToDeath(rl, 0);           } catch (RemoteException e) {               return sticky;           }           rl.linkedToDeath = true;       }       mRegisteredReceivers.put(receiver.asBinder(), rl);   }  

在里面查找有没有这个 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

向上跟踪

int NT = receivers != null ? receivers.size() : 0;   int it = 0;   ResolveInfo curt = null;   BroadcastFilter curr = null;   while (it < NT && ir < NR) {       if (curt == null) {           curt = (ResolveInfo)receivers.get(it);       }       if (curr == null) {           curr = registeredReceivers.get(ir);       }       if (curr.getPriority() >= curt.priority) {           // Insert this broadcast record into the final list.            receivers.add(it, curr);           ir++;           curr = null;           it++;           NT++;       } else {           // Skip to the next ResolveInfo in the final list.            it++;           curt = null;       }   }  

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

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwygjg.html