Android110426: Intent机制实现注记Email: zcatt@163.com
Blog http://zcatt.blog.chinaunix.net
内容提要Android如何寻找intent受体.以供备忘和参考。
声明仅限学习交流,禁止商业用途。转载需注明出处。
版本记录Date Ver Note
2011-04-26 0.1 Draft. zcatt, Beijing
Intent可以理解为一种异步通信机制. 发送者将目的地址和参数信息封装到Intent中发送出去. 而各个受体,包括activity, receiver和service, 使用intent-filter的方式告诉android系统自己可以处理的Intent种类. android系统根据Intent的目的地址解析Intent的受体. Intent的目的地址可以分为两类, 一类是明确定义了ComponentName, 对于此类intent, android系统直接查找所需的受体就可, 不存在匹配过程. 另一类则是没有定义ComponentName, 但是确通过对action, category和data的定义给出匹配信息, android系统根据这些信息查找系统内已经登记的所有受体的intentFilter信息, 匹配出合适的intent受体, 如果受体是多个,则按照priority和preference挑选出最适合的intent受体.
Intent整个机制主要相关的类包括如下, 下面分述之.
- Intent
- IntentFilter
- PackageParser.IntentInfo
- PackageParser.ActivityIntentInfo
- PackageParser.ServiceIntentInfo
- PackageManagerService.PreferredActivity
- ResolveInfo
- IntentResolver
- PackageManagerService.ActivityIntentResolver
- PackageManagerService.ServiceIntentResolver
IntentFilter描述的是intent filter, 对应的是AndroidManifest.xml中的
. 主要的成员包括:
- private int mPriority;
- private final ArrayList<String> mActions;
- private ArrayList<String> mCategories = null;
- private ArrayList<String> mDataSchemes = null;
- private ArrayList<AuthorityEntry> mDataAuthorities = null;
- private ArrayList<PatternMatcher> mDataPaths = null;
- private ArrayList<String> mDataTypes = null;
- private boolean mHasPartialTypes = false;
关键的方法是
- public final int match(String action, String type, String scheme,
- Uri data, Set<String> categories, String logTag)
IntentFilter的功用很简单, 就是判断(action, type, scheme, data, categories)是否匹配自己描述的intentFilter.
IntentResolver则是一个框架类, 可以将多个intentFilter组织起来. 输入intent, 遍历这些intentFilter,得到适合的intentFilter.
- public class IntentResolver<F extends IntentFilter, R extends Object>
其中F是intentFilter的类, R则是匹配intent后所得到的结果, 是关于适合intentFilter的信息.IntentResolver派生出两个子类PackageManagerService.ActivityIntentResolver和PackageManagerService.ServiceIntentResolver. 前者对应的是和相关的intentFilter, 后者对应的是相关的intentFilter.
- private final class ActivityIntentResolver
- extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo>
- private final class ServiceIntentResolver
- extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo>
IntentResolver重要的方法有3个
- public List<R> queryIntent(Intent intent, String resolvedType, boolean defaultOnly)
- protected R newResult(F filter, int match)
- protected boolean allowFilterResult(F filter, List<R> dest)
- protected void sortResults(List<R> results)
queryIntent()返回的是已经按照匹配程度排序的intent匹配结果列表, 实际就是适合输入参数intent的intentFilter的结果列表.在这个query过程中newResult(), allowFilterResult()和sortResults()会被queryIntent()调用, 而这个3个方法也通常是子类要考虑实现的.
newResult()用于将匹配的filter封装到R中.
allowFilterResult()可以控制筛选, 返回false的则会从结果dest中剔除, 通常allowFilterResult()被IntentResolver的子类用于防止dest中的重复添加相同filter, 如果dest中已经含有filter,则返回false.
sortResults()则对结果进行排序, 可以看到IntentResolver的排序规则是根据priority. 而ActivityIntentResolver和ServiceIntentResolver则复杂些, 还考虑了preferredOrder和intentFilter是否是default的情况, 细节参见PackageManagerService.mResolvePrioritySorter.
ActivityIntentInfo和ServiceIntentInfo是PackageParser解析xml, 容纳intentFilter描述信息的类.
- public static class IntentInfo extends IntentFilter
- public final static class ActivityIntentInfo extends IntentInfo
- public final static class ServiceIntentInfo extends IntentInfo
整个intent的解析场景是这样的, PackageManangerService调用PackageParser装载所有的filterIntent到mActivities, mReceivers和mServices. 这些信息将在query intent是被使用.
- // All available activities, for your resolving pleasure.
- final ActivityIntentResolver mActivities =
- new ActivityIntentResolver();
- // All available receivers, for your resolving pleasure.
- final ActivityIntentResolver mReceivers =
- new ActivityIntentResolver();
- // All available services, for your resolving pleasure.
- final ServiceIntentResolver mServices = new ServiceIntentResolver();
PackageManangerService提供以下的几个方法做为Android系统对intent机制的根本支持.
- public List<ResolveInfo> queryIntentActivities(Intent intent,
- String resolvedType, int flags)
- public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
- Intent[] specifics, String[] specificTypes, Intent intent,
- String resolvedType, int flags)
- public List<ResolveInfo> queryIntentReceivers(Intent intent,
- String resolvedType, int flags)
- public List<ResolveInfo> queryIntentServices(Intent intent,
- String resolvedType, int flags)
阅读(2135) | 评论(0) | 转发(0) |