如果,在短信攔截的軟件中,程序員們就發現了這個問題。 同一優先級的廣播接收器,動態的要比靜態注冊的早。
動態注冊:即由代碼注冊的廣播接收器
靜態注冊:即在 AndroidManifest.xml 中注冊的廣播接收器
優先級: 當廣播為有序發送的時候,要按這個排序並順序發送。
sendBroadcast 發送的是無序廣播。
sendOrderedBroadcast 發送的是有序廣播。
好了,現在尋找問題原因,在找原因前肯定有這樣的想法,一個有序隊列,既然允許有相同的優先級存在,那麼在同優先級內要不然有排序子因素,要不基就是按照某種操作可能影響順序。後者可能性很大。
打開源碼,順著 動態注冊廣播接受器 找,最後是 ActivityManagerService.java 這個文件找到了 registerReceiver 的實現。
同地也看到,存儲的廣播接收器列表是 HashMap mRegisteredReceivers 這個變理。
裡面有一段代碼為:
在裡面查找有沒有這個 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
向上跟蹤
發現了一段 對 receivers 排序的代碼,並且判斷也是 priority 的值,用的是 >= 方式
感覺的找到了地方,但是對 Activity Manager Service 這個模塊卻更加的不懂了,以後有機會一定要分析一下這塊是怎樣設計的,才能確定本文的問題所在。