一、概述
- 背景
- 在源码分析 — Activity的清单注册校验及动态注入一文中,我们通过
AppGlobals.getPackageManager()
方法获取了IPackageManager
的接口实现类PackageManagerService(PMS)
,由此引出了这篇文章;
-
版本
系统 版本 Android 23 -
关于
PackageManagerService
的初始化,请参考:
源码分析 — PackageManagerService(一)之启动流程
二、resolveIntent()解析
2.1 resolveIntent()解析时序图
2.2 resolveIntent()源码
// 从startActivity(Intent)进来,Intent不为null;
public ResolveInfo resolveIntent(Intent intent, String resolvedType,
int flags, int userId) {
// ...代码省略...
// 查询出满足Intent条件的ResolveInfo集合(如果该Activity没有在清单文件中注册过,则返回一个空集合)
List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
// 找出满足Intent条件的Activity(如果集合query为空,则直接回返null;)
return chooseBestActivity(intent, resolvedType, flags, query, userId);
}
public List<ResolveInfo> queryIntentActivities(Intent intent,
String resolvedType, int flags, int userId) {
// ...代码省略...
/*
* ComponentName对象内包含两个属性:
* 1.包名:mPackage
* 2.类名:mClass
*/
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
intent = intent.getSelector();
comp = intent.getComponent();
}
}
if (comp != null) {//执行这里
final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
// 根据所给的Component去清单文件中查找对应的ActivityInfo信息,如果没找到,则返回null;
final ActivityInfo ai = getActivityInfo(comp, flags, userId);
if (ai != null) {
final ResolveInfo ri = new ResolveInfo();
ri.activityInfo = ai;
list.add(ri);
}
// 如果根据所给的Component没有找到对应的ActivityInfo,则返回一个空集合;
return list;
}
// ...省略大段代码...
}
public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
// ...代码省略...
synchronized (mPackages) {
/*
* mActivities.mActivities的类型是ArrayMap<ComponentName, PackageParser.Activity>,这个属性字段在PackageManagerService.scanPackageDirtyLI()方法中被赋值;
* 如果Activity没有在清单文件中注册过,这里的 a=null;
*/
PackageParser.Activity a = mActivities.mActivities.get(component);
if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
if (ps == null) return null;
// 这里返回一个ActivityInfo实体(如果参数a=null,则该方法返回值也为null)
return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
userId);
}
if (mResolveComponentName.equals(component)) {
return PackageParser.generateActivityInfo(mResolveActivity, flags,
new PackageUserState(), userId);
}
}
return null;
}
/*
* 如果query是一个空集合,则直接回返null;
*/
private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
int flags, List<ResolveInfo> query, int userId) {
if (query != null) {
// 此处如果集合(query)为空,则直接回返null;
final int N = query.size();
if (N == 1) {
return query.get(0);
} else if (N > 1) {
// ...省略大段代码...
}
}
return null;
}
三、小结
PackageManagerService
初始化;PackageManagerService
启动时,会去搜索指定目录下的所有apk包;- 解析每个apk包里的
Manifest
(注册清单)文件; - 将解析出来的信息存储到
PackageParser.Package
对象中; - 将
PackageParser.Package
中的值赋值给PackageManagerService
中对应的字段;
PackageManagerService.resolveIntent(intent)
- 根据给定的
Intent
从PackageManagerService
中查找与之Intent.ComponentName
相匹配的Activity
集合; - 从查出来的集合中获取最为匹配的
Activity
;
- 根据给定的