Android 得到安装包的信息,主角得到未来的信息炒股小说
终极管理员 知识笔记 78阅读
一个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为truehidden 为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类对象就包含了安装包的信息。