一个APK安装包它的相关信息都配置在AndroidManifest.xml中,将它解析出来之后,是存放在PackageInfo类对象中,而PackageInfo类对象的生成相关代码,实现在PackageUtil类的getPackageInfo()方法中,看一下它的实现:
@Nullable
public static PackageInfo getPackageInfo(Context context, File sourceFile, int flags) {
try {
return context.getPackageManager().getPackageArchiveInfo(sourceFile.getAbsolutePath(),
flags);
} catch (Exception ignored) {
return null;
}
}
在这context一般是Activity实例,context.getPackageManager()得到的是ApplicationPackageManager实例。看一下它的getPackageArchiveInfo(sourceFile.getAbsolutePath(), flags)方法:
@Nullable
public PackageInfo getPackageArchiveInfo(@NonNull String archiveFilePath,
@PackageInfoFlags int flags) {
if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
| PackageManager.MATCH_DIRECT_BOOT_AWARE)) == 0) {
// Caller expressed no opinion about what encryption
// aware/unaware components they want to see, so match both
flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
}
boolean collectCertificates = (flags & PackageManager.GET_SIGNATURES) != 0
|| (flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0;
ParseInput input = ParseTypeImpl.forParsingWithoutPlatformCompat().reset();
ParseResult<ParsingPackage> result = ParsingPackageUtils.parseDefault(input,
new File(archiveFilePath), 0, getPermissionManager().getSplitPermissions(),
collectCertificates);
if (result.isError()) {
return null;
}
return PackageInfoWithoutStateUtils.generate(result.getResult(), null, flags, 0, 0, null,
new PackageUserState(), UserHandle.getCallingUserId());
}
在这里,会将 flags 添加PackageManager.MATCH_DIRECT_BOOT_AWARE和PackageManager.MATCH_DIRECT_BOOT_UNAWARE。collectCertificates 会为false,代表不会收集签名。
这里的input 实际是ParseTypeImpl对象。它用来保存解析的结果。
这里首先通过ParsingPackageUtils.parseDefault()得到APK安装包的解析信息,然后调用PackageInfoWithoutStateUtils.generate()得到PackageInfo对象。
看一下PackageInfoWithoutStateUtils.generate()方法,了解一下PackageInfo对象是怎么生成的。这里UserHandle.getCallingUserId()是Binder调用方的user id,它是通过调用方的uid得到的,如果当前没处在Binder调用中,则它是当前应用的user id。
PackageInfoWithoutStateUtils.generate()方法会在内部调用PackageInfoWithoutStateUtils的静态方法generateWithComponents(ParsingPackageRead pkg, int[] gids, @PackageManager.PackageInfoFlags int flags, long firstInstallTime, long lastUpdateTime, Set grantedPermissions, PackageUserState state, int userId, @Nullable ApexInfo apexInfo),看一下它的实现:
@Nullable
private static PackageInfo generateWithComponents(ParsingPackageRead pkg, int[] gids,
@PackageManager.PackageInfoFlags int flags, long firstInstallTime, long lastUpdateTime,
Set<String> grantedPermissions, PackageUserState state, int userId,
@Nullable ApexInfo apexInfo) {
ApplicationInfo applicationInfo = generateApplicationInfo(pkg, flags, state, userId);
if (applicationInfo == null) {
return null;
}
PackageInfo info = generateWithoutComponents(pkg, gids, flags, firstInstallTime,
lastUpdateTime, grantedPermissions, state, userId, apexInfo, applicationInfo);
if (info == null) {
return null;
}
if ((flags & PackageManager.GET_ACTIVITIES) != 0) {
final int N = pkg.getActivities().size();
if (N > 0) {
int num = 0;
final ActivityInfo[] res = new ActivityInfo[N];
for (int i = 0; i < N; i++) {
final ParsedActivity a = pkg.getActivities().get(i);
if (ComponentParseUtils.isMatch(state, false, pkg.isEnabled(), a,
flags)) {
if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(
a.getName())) {
continue;
}
res[num++] = generateActivityInfo(pkg, a, flags, state,
applicationInfo, userId);
}
}
info.activities = ArrayUtils.trimToSize(res, num);
}
}
if ((flags & PackageManager.GET_RECEIVERS) != 0) {
final int size = pkg.getReceivers().size();
if (size > 0) {
int num = 0;
final ActivityInfo[] res = new ActivityInfo[size];
for (int i = 0; i < size; i++) {
final ParsedActivity a = pkg.getReceivers().get(i);
if (ComponentParseUtils.isMatch(state, false, pkg.isEnabled(), a,
flags)) {
res[num++] = generateActivityInfo(pkg, a, flags, state,
applicationInfo, userId);
}
}
info.receivers = ArrayUtils.trimToSize(res, num);
}
}
if ((flags & PackageManager.GET_SERVICES) != 0) {
final int size = pkg.getServices().size();
if (size > 0) {
int num = 0;
final ServiceInfo[] res = new ServiceInfo[size];
for (int i = 0; i < size; i++) {
final ParsedService s = pkg.getServices().get(i);
if (ComponentParseUtils.isMatch(state, false, pkg.isEnabled(), s,
flags)) {
res[num++] = generateServiceInfo(pkg, s, flags, state,
applicationInfo, userId);
}
}
info.services = ArrayUtils.trimToSize(res, num);
}
}
if ((flags & PackageManager.GET_PROVIDERS) != 0) {
final int size = pkg.getProviders().size();
if (size > 0) {
int num = 0;
final ProviderInfo[] res = new ProviderInfo[size];
for (int i = 0; i < size; i++) {
final ParsedProvider pr = pkg.getProviders()
.get(i);
if (ComponentParseUtils.isMatch(state, false, pkg.isEnabled(), pr,
flags)) {
res[num++] = generateProviderInfo(pkg, pr, flags, state,
applicationInfo, userId);
}
}
info.providers = ArrayUtils.trimToSize(res, num);
}
}
if ((flags & PackageManager.GET_INSTRUMENTATION) != 0) {
int N = pkg.getInstrumentations().size();
if (N > 0) {
info.instrumentation = new InstrumentationInfo[N];
for (int i = 0; i < N; i++) {
info.instrumentation[i] = generateInstrumentationInfo(
pkg.getInstrumentations().get(i), pkg, flags, userId,
true /* assignUserFields */);
}
}
}
return info;
}
该方法首先通过generateApplicationInfo()方法得到ApplicationInfo对象,然后通过该对象作为参数调用generateWithoutComponents()方法得到PackageInfo对象info。接下来,再根据flags标识判断是否得到四大组件Activity、Receiver、Service、Provider的信息。再通过PackageManager.GET_INSTRUMENTATION标识,得到Instrumentation信息。
它是由PackageInfoWithoutStateUtils类的generateApplicationInfo(ParsingPackageRead pkg, @PackageManager.ApplicationInfoFlags int flags, PackageUserState state, int userId)实现:
@Nullable
public static ApplicationInfo generateApplicationInfo(ParsingPackageRead pkg,
@PackageManager.ApplicationInfoFlags int flags, PackageUserState state, int userId) {
if (pkg == null) {
return null;
}
if (!checkUseInstalled(pkg, state, flags)) {
return null;
}
return generateApplicationInfoUnchecked(pkg, flags, state, userId,
true /* assignUserFields */);
}
pkg 不问为null,它是解析APK文件得到的所有相关信息,它实际是ParsingPackageImpl对象。详细见Android 解析APK包。
接着调用checkUseInstalled(pkg, state, flags)检查包的状态,如果返回false,则返回结果null。PackageUserState类用来描述包的每用户状态信息。它最终是调用PackageUserState类对象的isAvailable(int flags)方法实现,代码PackageUserState类对象的isAvailable(int flags)代码如下:
/**
* Test if this package is installed.
*/
public boolean isAvailable(int flags) {
// True if it is installed for this user and it is not hidden. If it is hidden,
// still return true if the caller requested MATCH_UNINSTALLED_PACKAGES
final boolean matchAnyUser = (flags & PackageManager.MATCH_ANY_USER) != 0;
final boolean matchUninstalled = (flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0;
return matchAnyUser
|| (this.installed
&& (!this.hidden || matchUninstalled));
}
如果标签flags存在PackageManager.MATCH_ANY_USER标识,则代表满足任一用户。这种情况直接返回true。
如果状态是installed并且不是隐藏,返回true。但是状态是installed并且是隐藏,这种情况下调用者如果带PackageManager.MATCH_UNINSTALLED_PACKAGES标识也返回true。
在这里PackageUserState类对象是新建的,所以installed为true,hidden 为false。所以返回true。
最后接着调用generateApplicationInfoUnchecked(pkg, flags, state, userId, true /* assignUserFields */),来生成ApplicationInfo对象,它的代码如下:
@NonNull
public static ApplicationInfo generateApplicationInfoUnchecked(@NonNull ParsingPackageRead pkg,
@PackageManager.ApplicationInfoFlags int flags, PackageUserState state, int userId,
boolean assignUserFields) {
// Make shallow copy so we can store the metadata/libraries safely
ApplicationInfo ai = pkg.toAppInfoWithoutState();
if (assignUserFields) {
assignUserFields(pkg, ai, userId);
}
if ((flags & PackageManager.GET_META_DATA) == 0) {
ai.metaData = null;
}
if ((flags & PackageManager.GET_SHARED_LIBRARY_FILES) == 0) {
ai.sharedLibraryFiles = null;
ai.sharedLibraryInfos = null;
}
// CompatibilityMode is global state.
if (!android.content.pm.PackageParser.sCompatibilityModeEnabled) {
ai.disableCompatibilityMode();
}
ai.flags |= flag(state.stopped, ApplicationInfo.FLAG_STOPPED)
| flag(state.installed, ApplicationInfo.FLAG_INSTALLED)
| flag(state.suspended, ApplicationInfo.FLAG_SUSPENDED);
ai.privateFlags |= flag(state.instantApp, ApplicationInfo.PRIVATE_FLAG_INSTANT)
| flag(state.virtualPreload, ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD)
| flag(state.hidden, ApplicationInfo.PRIVATE_FLAG_HIDDEN);
if (state.enabled == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
ai.enabled = true;
} else if (state.enabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
ai.enabled = (flags & PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS) != 0;
} else if (state.enabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED
|| state.enabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
ai.enabled = false;
}
ai.enabledSetting = state.enabled;
if (ai.category == ApplicationInfo.CATEGORY_UNDEFINED) {
ai.category = state.categoryHint;
}
if (ai.category == ApplicationInfo.CATEGORY_UNDEFINED) {
ai.category = FallbackCategoryProvider.getFallbackCategory(ai.packageName);
}
ai.seInfoUser = SELinuxUtil.assignSeinfoUser(state);
final OverlayPaths overlayPaths = state.getAllOverlayPaths();
if (overlayPaths != null) {
ai.resourceDirs = overlayPaths.getResourceDirs().toArray(new String[0]);
ai.overlayPaths = overlayPaths.getOverlayPaths().toArray(new String[0]);
}
return ai;
}
这里通过ParsingPackageRead类对象pkg的toAppInfoWithoutState()得到ApplicationInfo对象。这里pkg是ParsingPackageImpl对象。所以这里调用的ParsingPackageImpl类的toAppInfoWithoutState()方法:
@Deprecated
@Override
public ApplicationInfo toAppInfoWithoutState() {
ApplicationInfo appInfo = toAppInfoWithoutStateWithoutFlags();
appInfo.flags = PackageInfoWithoutStateUtils.appInfoFlags(this);
appInfo.privateFlags = PackageInfoWithoutStateUtils.appInfoPrivateFlags(this);
appInfo.privateFlagsExt = PackageInfoWithoutStateUtils.appInfoPrivateFlagsExt(this);
return appInfo;
}
@Override
public ApplicationInfo toAppInfoWithoutStateWithoutFlags() {
ApplicationInfo appInfo = new ApplicationInfo();
// Lines that are commented below are state related and should not be assigned here.
// They are left in as placeholders, since there is no good backwards compatible way to
// separate these.
appInfo.appComponentFactory = appComponentFactory;
appInfo.backupAgentName = backupAgentName;
appInfo.banner = banner;
appInfo.category = category;
appInfo.classLoaderName = classLoaderName;
appInfo.className = className;
appInfo.compatibleWidthLimitDp = compatibleWidthLimitDp;
appInfo.compileSdkVersion = compileSdkVersion;
appInfo.compileSdkVersionCodename = compileSdkVersionCodeName;
// appInfo.credentialProtectedDataDir
appInfo.crossProfile = isCrossProfile();
// appInfo.dataDir
appInfo.descriptionRes = descriptionRes;
// appInfo.deviceProtectedDataDir
appInfo.enabled = getBoolean(Booleans.ENABLED);
// appInfo.enabledSetting
appInfo.fullBackupContent = fullBackupContent;
appInfo.dataExtractionRulesRes = dataExtractionRules;
// TODO(b/135203078): See ParsingPackageImpl#getHiddenApiEnforcementPolicy
// appInfo.mHiddenApiPolicy
// appInfo.hiddenUntilInstalled
appInfo.icon =
(ParsingPackageUtils.sUseRoundIcon && roundIconRes != 0) ? roundIconRes : iconRes;
appInfo.iconRes = iconRes;
appInfo.roundIconRes = roundIconRes;
appInfo.installLocation = installLocation;
appInfo.labelRes = labelRes;
appInfo.largestWidthLimitDp = largestWidthLimitDp;
appInfo.logo = logo;
appInfo.manageSpaceActivityName = manageSpaceActivityName;
appInfo.maxAspectRatio = maxAspectRatio;
appInfo.metaData = metaData;
appInfo.minAspectRatio = minAspectRatio;
appInfo.minSdkVersion = minSdkVersion;
appInfo.name = className;
// appInfo.nativeLibraryDir
// appInfo.nativeLibraryRootDir
// appInfo.nativeLibraryRootRequiresIsa
appInfo.networkSecurityConfigRes = networkSecurityConfigRes;
appInfo.nonLocalizedLabel = nonLocalizedLabel;
appInfo.packageName = packageName;
appInfo.permission = permission;
// appInfo.primaryCpuAbi
appInfo.processName = getProcessName();
appInfo.requiresSmallestWidthDp = requiresSmallestWidthDp;
// appInfo.resourceDirs
// appInfo.secondaryCpuAbi
// appInfo.secondaryNativeLibraryDir
// appInfo.seInfo
// appInfo.seInfoUser
// appInfo.sharedLibraryFiles
// appInfo.sharedLibraryInfos
// appInfo.showUserIcon
appInfo.splitClassLoaderNames = splitClassLoaderNames;
appInfo.splitDependencies = splitDependencies;
appInfo.splitNames = splitNames;
appInfo.storageUuid = mStorageUuid;
appInfo.targetSandboxVersion = targetSandboxVersion;
appInfo.targetSdkVersion = targetSdkVersion;
appInfo.taskAffinity = taskAffinity;
appInfo.theme = theme;
// appInfo.uid
appInfo.uiOptions = uiOptions;
appInfo.volumeUuid = volumeUuid;
appInfo.zygotePreloadName = zygotePreloadName;
appInfo.setGwpAsanMode(gwpAsanMode);
appInfo.setMemtagMode(memtagMode);
appInfo.setNativeHeapZeroInitialized(nativeHeapZeroInitialized);
appInfo.setRequestRawExternalStorageAccess(requestRawExternalStorageAccess);
appInfo.setBaseCodePath(mBaseApkPath);
appInfo.setBaseResourcePath(mBaseApkPath);
appInfo.setCodePath(mPath);
appInfo.setResourcePath(mPath);
appInfo.setSplitCodePaths(splitCodePaths);
appInfo.setSplitResourcePaths(splitCodePaths);
appInfo.setVersionCode(mLongVersionCode);
return appInfo;
}
从这里可以看到,主要是将ParsingPackageImpl对象的成员变量值赋给ApplicationInfo 类对象。
再回到PackageInfoWithoutStateUtils类的generateApplicationInfoUnchecked(pkg, flags, state, userId, true /* assignUserFields */)方法里,接着assignUserFields如果为true,会调用assignUserFields(pkg, ai, userId),它主要是设置ApplicationInfo类对象的credentialProtectedDataDir、deviceProtectedDataDir、dataDir。
接着会根据标识,判断是否设置ApplicationInfo类对象的metaData、sharedLibraryFiles、sharedLibraryInfos。
下面主要是根据PackageUserState类对象state的值来设置一些对应的值。
通过以上,我们明白了ApplicationInfo类对象的生成。
PackageInfo对象的生成主要是由PackageInfoWithoutStateUtils的generateWithoutComponents(ParsingPackageRead pkg, int[] gids, @PackageManager.PackageInfoFlags int flags, long firstInstallTime, long lastUpdateTime, Set grantedPermissions, PackageUserState state, int userId, @Nullable ApexInfo apexInfo, @NonNull ApplicationInfo applicationInfo)来生成,看一下它的代码:
@Nullable
public static PackageInfo generateWithoutComponents(ParsingPackageRead pkg, int[] gids,
@PackageManager.PackageInfoFlags int flags, long firstInstallTime, long lastUpdateTime,
Set<String> grantedPermissions, PackageUserState state, int userId,
@Nullable ApexInfo apexInfo, @NonNull ApplicationInfo applicationInfo) {
if (!checkUseInstalled(pkg, state, flags)) {
return null;
}
return generateWithoutComponentsUnchecked(pkg, gids, flags, firstInstallTime,
lastUpdateTime, grantedPermissions, state, userId, apexInfo, applicationInfo);
}
checkUseInstalled(pkg, state, flags)前面说过了,这里略了。接着看generateWithoutComponentsUnchecked()方法:
@NonNull
public static PackageInfo generateWithoutComponentsUnchecked(ParsingPackageRead pkg, int[] gids,
@PackageManager.PackageInfoFlags int flags, long firstInstallTime, long lastUpdateTime,
Set<String> grantedPermissions, PackageUserState state, int userId,
@Nullable ApexInfo apexInfo, @NonNull ApplicationInfo applicationInfo) {
PackageInfo pi = new PackageInfo();
pi.packageName = pkg.getPackageName();
pi.splitNames = pkg.getSplitNames();
pi.versionCode = pkg.getVersionCode();
pi.versionCodeMajor = pkg.getVersionCodeMajor();
pi.baseRevisionCode = pkg.getBaseRevisionCode();
pi.splitRevisionCodes = pkg.getSplitRevisionCodes();
pi.versionName = pkg.getVersionName();
pi.sharedUserId = pkg.getSharedUserId();
pi.sharedUserLabel = pkg.getSharedUserLabel();
pi.applicationInfo = applicationInfo;
pi.installLocation = pkg.getInstallLocation();
if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
|| (pi.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
pi.requiredForAllUsers = pkg.isRequiredForAllUsers();
}
pi.restrictedAccountType = pkg.getRestrictedAccountType();
pi.requiredAccountType = pkg.getRequiredAccountType();
pi.overlayTarget = pkg.getOverlayTarget();
pi.targetOverlayableName = pkg.getOverlayTargetName();
pi.overlayCategory = pkg.getOverlayCategory();
pi.overlayPriority = pkg.getOverlayPriority();
pi.mOverlayIsStatic = pkg.isOverlayIsStatic();
pi.compileSdkVersion = pkg.getCompileSdkVersion();
pi.compileSdkVersionCodename = pkg.getCompileSdkVersionCodeName();
pi.firstInstallTime = firstInstallTime;
pi.lastUpdateTime = lastUpdateTime;
if ((flags & PackageManager.GET_GIDS) != 0) {
pi.gids = gids;
}
if ((flags & PackageManager.GET_CONFIGURATIONS) != 0) {
int size = pkg.getConfigPreferences().size();
if (size > 0) {
pi.configPreferences = new ConfigurationInfo[size];
pkg.getConfigPreferences().toArray(pi.configPreferences);
}
size = pkg.getReqFeatures().size();
if (size > 0) {
pi.reqFeatures = new FeatureInfo[size];
pkg.getReqFeatures().toArray(pi.reqFeatures);
}
size = pkg.getFeatureGroups().size();
if (size > 0) {
pi.featureGroups = new FeatureGroupInfo[size];
pkg.getFeatureGroups().toArray(pi.featureGroups);
}
}
if ((flags & PackageManager.GET_PERMISSIONS) != 0) {
int size = ArrayUtils.size(pkg.getPermissions());
if (size > 0) {
pi.permissions = new PermissionInfo[size];
for (int i = 0; i < size; i++) {
pi.permissions[i] = generatePermissionInfo(pkg.getPermissions().get(i),
flags);
}
}
final List<ParsedUsesPermission> usesPermissions = pkg.getUsesPermissions();
size = usesPermissions.size();
if (size > 0) {
pi.requestedPermissions = new String[size];
pi.requestedPermissionsFlags = new int[size];
for (int i = 0; i < size; i++) {
final ParsedUsesPermission usesPermission = usesPermissions.get(i);
pi.requestedPermissions[i] = usesPermission.name;
// The notion of required permissions is deprecated but for compatibility.
pi.requestedPermissionsFlags[i] |=
PackageInfo.REQUESTED_PERMISSION_REQUIRED;
if (grantedPermissions != null
&& grantedPermissions.contains(usesPermission.name)) {
pi.requestedPermissionsFlags[i] |=
PackageInfo.REQUESTED_PERMISSION_GRANTED;
}
if ((usesPermission.usesPermissionFlags
& ParsedUsesPermission.FLAG_NEVER_FOR_LOCATION) != 0) {
pi.requestedPermissionsFlags[i] |=
PackageInfo.REQUESTED_PERMISSION_NEVER_FOR_LOCATION;
}
}
}
}
if ((flags & PackageManager.GET_ATTRIBUTIONS) != 0) {
int size = ArrayUtils.size(pkg.getAttributions());
if (size > 0) {
pi.attributions = new Attribution[size];
for (int i = 0; i < size; i++) {
pi.attributions[i] = generateAttribution(pkg.getAttributions().get(i));
}
}
if (pkg.areAttributionsUserVisible()) {
pi.applicationInfo.privateFlagsExt
|= ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE;
} else {
pi.applicationInfo.privateFlagsExt
&= ~ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE;
}
} else {
pi.applicationInfo.privateFlagsExt
&= ~ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE;
}
if (apexInfo != null) {
File apexFile = new File(apexInfo.modulePath);
pi.applicationInfo.sourceDir = apexFile.getPath();
pi.applicationInfo.publicSourceDir = apexFile.getPath();
if (apexInfo.isFactory) {
pi.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
} else {
pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
pi.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
}
if (apexInfo.isActive) {
pi.applicationInfo.flags |= ApplicationInfo.FLAG_INSTALLED;
} else {
pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_INSTALLED;
}
pi.isApex = true;
}
PackageParser.SigningDetails signingDetails = pkg.getSigningDetails();
// deprecated method of getting signing certificates
if ((flags & PackageManager.GET_SIGNATURES) != 0) {
if (signingDetails.hasPastSigningCertificates()) {
// Package has included signing certificate rotation information. Return the oldest
// cert so that programmatic checks keep working even if unaware of key rotation.
pi.signatures = new Signature[1];
pi.signatures[0] = signingDetails.pastSigningCertificates[0];
} else if (signingDetails.hasSignatures()) {
// otherwise keep old behavior
int numberOfSigs = signingDetails.signatures.length;
pi.signatures = new Signature[numberOfSigs];
System.arraycopy(signingDetails.signatures, 0, pi.signatures, 0,
numberOfSigs);
}
}
// replacement for GET_SIGNATURES
if ((flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0) {
if (signingDetails != PackageParser.SigningDetails.UNKNOWN) {
// only return a valid SigningInfo if there is signing information to report
pi.signingInfo = new SigningInfo(signingDetails);
} else {
pi.signingInfo = null;
}
}
return pi;
}
这些代码看着很长,其实主要是新生成PackageInfo对象,然后给它的成员变量赋值。
这里我们看到,前面生成的ApplicationInfo类对象是放到PackageInfo类对象的applicationInfo成员变量中。并且PackageInfo类对象大部分成员变量的值都来自ParsingPackageImpl类对象的成员变量的值。
而ApplicationInfo类对象的值,大部分也都来自ParsingPackageImpl类对象。而ParsingPackageImpl类对象的值,也是来自安装包里的“AndroidManifest.xml”文件,这样就将ParsingPackageImpl类对象的值都设置到PackageInfo类对象中。
APK安装包里的配置信息都在“AndroidManifest.xml”文件中,通过解析它之后,是放到了ParsingPackageImpl类对象中。ParsingPackageImpl类对象通过自己的toAppInfoWithoutState(),将自己的值生成到ApplicationInfo对象中,而PackageInfo类对象的applicationInfo正是ApplicationInfo对象,并且PackageInfo类对象的其他成员也来自ParsingPackageImpl类对象。这样PackageInfo类对象就包含了安装包的信息。