欢迎来到飞鸟慕鱼博客,开始您的技术之旅!
当前位置: 首页知识笔记正文

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信息。

生成ApplicationInfo对象

  它是由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对象

  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类对象就包含了安装包的信息。

标签:
声明:无特别说明,转载请标明本文来源!