读书人

android安全有关问题(七) 抢先接收广

发布时间: 2013-02-18 10:50:49 作者: rapoo

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/

读书人网 >Android

热点推荐