PMS服务
PackageParser类
它主要是用来解析手机上的apk文件的,它主要有2个过程:
- APK -> Package:将apk文件解析成package对象
- Package -> PackageInfo:由package对象生成PackageInfo对象
APK -> Package
public Package parsePackage(File packageFile, int flags, boolean useCaches)
throws PackageParserException {
Package parsed = useCaches ? getCachedResult(packageFile, flags) : null;
if (parsed != null) {
return parsed;
}
if (packageFile.isDirectory()) {
parsed = parseClusterPackage(packageFile, flags);
} else {
parsed = parseMonolithicPackage(packageFile, flags);
}
cacheResult(packageFile, flags, parsed);
return parsed;
}
这个最后走到:
private Package parseBaseApkCommon(Package pkg, Set<String> acceptedTags, Resources res,
XmlResourceParser parser, int flags, String[] outError) throws XmlPullParserException,
IOException { throws XmlPullParserException, IOException {
//....省略多行代码....
//循环解析AndroidManifest.xml中的元素
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
if (tagName.equals("application")) {
//....省略多行代码,重点关注其中调用的parseBaseApplication()方法
}else if (tagName.equals("overlay")) {
//....省略多行代码....
}else if (tagName.equals("key-sets")){
//paseKeySets()
}else if (tagName.equals("permission-group")) {
parsePermissionGroup(pkg, flags, res, parser, attrs,
}else if (tagName.equals("permission")) {
//parsePermission
}else if (tagName.equals("uses-configuration")) {
//....省略多行代码....
}else if (tagName.equals("uses-feature")) {
//parseUsesFeature()
}else if (tagName.equals("feature-group")) {
//....省略多行代码....
}else if (tagName.equals("uses-sdk")) {
//....省略多行代码....
}else if (tagName.equals("supports-screens")) {
//....省略多行代码....
}else if (tagName.equals("protected-broadcast")) {
//....省略多行代码....
}else if (tagName.equals("instrumentation")) {
//....省略多行代码....
}else if (tagName.equals("original-package")) {
//....省略多行代码....
}else if (tagName.equals("adopt-permissions")) {
//....省略多行代码....
}
//....省略多行代码....
}
//....省略多汗代码....
}
其中主要的是parseBaseApplication
这个方法:
private boolean parseBaseApplication(Package owner, Resources res,
XmlPullParser parser, AttributeSet attrs, int flags, String[] outError)
throws XmlPullParserException, IOException {
//....省略对Application元素属性解析多行代码....
//解析Application下的子元素结点,如activity,receiver,service等
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
if (tagName.equals("activity")) {
//....省略多行代码,主要关注parseActivity()....
} else if (tagName.equals("receiver")) {
//....省略多行代码,主要关注parseActivity()....
}else if (tagName.equals("service")) {
//....省略多行代码,主要关注parseService()....
}else if (tagName.equals("provider")) {
//....省略多行代码,主要关注parseProvider()....
}else if (tagName.equals("activity-alias")) {
//....省略多行代码,主要关注parseActivityAlias()...
}else if (parser.getName().equals("meta-data")) {
//....省略多行代码,重点关注parseMetaData()....
}else if (tagName.equals("library")) {
//....省略多行代码....
}else if (tagName.equals("uses-library")) {
//....省略多行代码....
}else if (tagName.equals("uses-package")) {
//....省略多行代码....
}else{
//....省略多行代码....
}
}
return true;
}
这里的会涉及到很多解析方法,如parseKeySets(),parsePermissionGroup(),parseUsesPermission(),都是以parse开头的。
Package -> PackageInfo
public static PackageInfo generatePackageInfo(PackageParser.Package p,
int gids[], int flags, long firstInstallTime, long lastUpdateTime,
ArraySet<String> grantedPermissions, PackageUserState state) {
return generatePackageInfo(p, gids, flags, firstInstallTime, lastUpdateTime,
grantedPermissions, state, UserHandle.getCallingUserId());
}
实际操作的类:
public static PackageInfo generatePackageInfo(PackageParser.Package p,
int gids[], int flags, long firstInstallTime, long lastUpdateTime,
ArraySet<String> grantedPermissions, PackageUserState state, int userId)
if (!checkUseInstalledOrHidden(flags, state)) {
return null;
}
//从Package对象p中取出一系列的属性值用来初始化pi
PackageInfo pi = new PackageInfo();
pi.packageName = p.packageName;
pi.splitNames = p.splitNames;
pi.versionCode = p.mVersionCode;
pi.baseRevisionCode = p.baseRevisionCode;
pi.splitRevisionCodes = p.splitRevisionCodes;
pi.versionName = p.mVersionName;
pi.sharedUserId = p.mSharedUserId;
pi.sharedUserLabel = p.mSharedUserLabel;
pi.applicationInfo = generateApplicationInfo(p, flags, state, userId);
pi.installLocation = p.installLocation;
pi.coreApp = p.coreApp;
if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0
|| (pi.applicationInfo.flags&ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
pi.requiredForAllUsers = p.mRequiredForAllUsers;
}
pi.restrictedAccountType = p.mRestrictedAccountType;
pi.requiredAccountType = p.mRequiredAccountType;
pi.overlayTarget = p.mOverlayTarget;
pi.firstInstallTime = firstInstallTime;
pi.lastUpdateTime = lastUpdateTime;
if ((flags&PackageManager.GET_GIDS) != 0) {
pi.gids = gids;
}
if ((flags&PackageManager.GET_CONFIGURATIONS) != 0) {
//....省略多行代码....
}
if ((flags&PackageManager.GET_ACTIVITIES) != 0) {
//....省略多行代码,关注generateActivityInfo()....
}
if ((flags&PackageManager.GET_RECEIVERS) != 0) {
//....省略多行代码,关注generateActivityInfo()....
}
if ((flags&PackageManager.GET_SERVICES) != 0) {
//....省略多行代码,关注generateServiceInfo()....
}
if ((flags&PackageManager.GET_PROVIDERS) != 0) {
//....省略多行代码,关注generateProviderInfo()....
}
if ((flags&PackageManager.GET_INSTRUMENTATION) != 0) {
//....省略多行代码,关注generateInstrumentationInfo()....
}
if ((flags&PackageManager.GET_PERMISSIONS) != 0) {
//....省略多行代码,generatePermissionInfo....
}
if ((flags&PackageManager.GET_SIGNATURES) != 0) {
//....省略多行代码....
}
return pi;
}
可以看出,这个过程和解析的过程很相近,是以generate开头的方法实现的。
实体类
主要是Package
和PackageInfo
实体类。
- Package代表磁盘上APK文件完整解析后的对象,相当于在内存中Package的对象对磁盘APK的描述
- PackageInfo代表AndroidManifest.xml中的信息
其他实体的介绍: