android安全问题(七) 抢先接收广播 - 内因篇之广播发送流程
导读:本文说明系统发送广播的部分流程,如何利用Intent查找到对应接收器。我们依然只关注接收器的排序问题
这篇文章主要是针对我前两篇文章
android安全问题(四) 抢先开机启动 - 结果篇
android安全问题(五) 抢先拦截短信 - 结果篇
现在给出第二步分的分析
下面就来看看发送广播的流程
Context中的sendBroadCast函数的实现是在ContextImpl中,和发送广播相关的有如下六个函数
void android.app.ContextImpl.sendBroadcast(Intent intent)
void android.app.ContextImpl.sendBroadcast(Intent intent, String receiverPermission)
void android.app.ContextImpl.sendOrderedBroadcast(Intent intent, String receiverPermission)
void android.app.ContextImpl.sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)
void android.app.ContextImpl.sendStickyBroadcast(Intent intent)
void android.app.ContextImpl.sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)
可以分为3组:1普通广播;2Ordered广播;3Sticky广播
不论哪种,最后都会由ActivityManagerService处理
ordered和sticky用来区分上面3组广播
下面我们仔细看看这个方法都干了些什么
删减了一些代码
public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags) { //ComponentName之后应该均为null,我们不讨论只发给特定组件的情况,因为那样不涉及优先级和顺序的问题 ComponentName comp = intent.getComponent(); if (comp == null) { if (intent.getSelector() != null) { intent = intent.getSelector(); comp = intent.getComponent(); } } if (comp != null) { List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); ActivityInfo ai = getReceiverInfo(comp, flags); if (ai != null) { ResolveInfo ri = new ResolveInfo(); ri.activityInfo = ai; list.add(ri); } return list; } // reader //ComponentName=null,所以会执行下面代码 synchronized (mPackages) { String pkgName = intent.getPackage(); //只考虑pkgName=null的情况,同一个package中,哪个receiver先接收到广播暂时不关心 if (pkgName == null) { return mReceivers.queryIntent(intent, resolvedType, flags);//最终会调用IntentResolver.queryIntent,上面已经分析过 } final PackageParser.Package pkg = mPackages.get(pkgName); if (pkg != null) { return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers); } return null; }}现在看来,上面两个查询都是按优先级从高到低排序的,如果优先级相同,顺序则保持不变
之后是调用scheduleBroadcastsLocked来发广播给每一个receiver
至于广播后续如何处理,我们就不再深究了
到这里已经能看到应用中的接收顺序了
总结:
情况分为两种(scheduleBroadcastsLocked),ordered广播和非ordered广播
非ordered广播
先处理动接收器,然后处理静态接收器
ordered广播
同时处理动态接收器和静态接收器
先将动态接收器与静态接收器合并,保持着与优先级相同的顺序,优先级高的在前面,否则顺序不变。静态接收器与动态接收器优先级相同的话,动态接收器在前
转贴请保留以下链接
本人blog地址
http://su1216.iteye.com/
http://blog.csdn.net/su1216/