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开头的方法实现的。

实体类

主要是PackagePackageInfo实体类。

  • Package代表磁盘上APK文件完整解析后的对象,相当于在内存中Package的对象对磁盘APK的描述
  • PackageInfo代表AndroidManifest.xml中的信息

其他实体的介绍:

results matching ""

    No results matching ""