APK安装过程

安装过程:

PackageManagerService的installStage方法负责安装应用:

void installStage(){
	 final Message msg = mHandler.obtainMessage(INIT_COPY);
	 final InstallParams params = new InstallParams(origin, null, observer,
                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
                verificationInfo, user, sessionParams.abiOverride,
                sessionParams.grantedRuntimePermissions, certificates, installReason);//2
     params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
     msg.obj = params;
     //PackageHandler发送一个INIT_COPY标记,和InstallParams参数
     mHandler.sendMessage(msg);
}

PackageHandler对INIT_COPY消息的处理:

case INIT_COPY: {
 	HandlerParams params = (HandlerParams) msg.obj;
 	if (!mBound) {					//用于标识是否绑定了DefaultContainerService,默认值为false
 		connectToService()			//绑定服务,并把mBound置为true,并发送MCS_BOUND类型的message
 	}else{
		//绑定服务成功,将请求添加到ArrayList类型的mPendingInstalls中,等待处理
        mPendingInstalls.add(idx, params);
	}
}

DefaultContainerService是用于检查和复制可移动文件的服务,这是一个比较耗时的操作,因此DefaultContainerService没有和PMS运行在同一进程中

PackageHandler对MCS_BOUND消息的处理:

if (mPendingInstalls.size() > 0) {
	//从安装列表里获取第一个任务
	HandlerParams params = mPendingInstalls.get(0);
	if (params.startCopy()) {		//开始复制APK,完成后返回true
		//如果APK安装成功,删除本次安装请求
        if (mPendingInstalls.size() > 0) {
        	mPendingInstalls.remove(0);
        }
		if (mPendingInstalls.size() == 0) {
			//如果没有安装请求了,发送解绑服务的message
			removeMessages(MCS_UNBIND);
            Message ubmsg = obtainMessage(MCS_UNBIND);
            sendMessageDelayed(ubmsg, 10000);
		} else {
			//如果还有其他的安装请求,接着发送MCS_BOUND消息继续处理剩余的安装请求      
			 mHandler.sendEmptyMessage(MCS_BOUND);
		}
	}
}

HandlerParams.startCopy()方法:

 	final boolean startCopy() {
            boolean res;
            try {
                if (++mRetries > MAX_RETRIES) {
                 	//startCopy方法尝试的次数,超过了4次,就放弃这个安装请求
                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
                    handleServiceError();
                    return false;
                } else {
                    handleStartCopy();
                    res = true;
                }
            } catch (RemoteException e) {
                mHandler.sendEmptyMessage(MCS_RECONNECT);
                res = false;
            }
            handleReturnCode();
            return res;
    }

InstallParams.handleStartCopy()方法:

 	public void handleStartCopy() throws RemoteException {
            //onSd:安装到SD卡;   
            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
            //onInt:内部存储即Data分区;
            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
            //ephemeral:安装到临时存储(Instant Apps安装)        
            final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
            PackageInfoLite pkgLite = null;
            if (onInt && onSd) {
              	// APK不能同时安装在SD卡和Data分区
                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
            } else if (onSd && ephemeral) {
            	//安装标志冲突,Instant Apps不能安装到SD卡中
                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
            } else {
                 //获取APK的少量的信息
                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
                        packageAbiOverride);
            if (ret == PackageManager.INSTALL_SUCCEEDED) {
                 //判断安装的位置
                int loc = pkgLite.recommendedInstallLocation;
                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
                } 
                ...
                }else{
                  //确定APK的安装位置
                  loc = installLocationPolicy(pkgLite);
                  ...
                }
            }
            //根据InstallParams创建InstallArgs对象
            //InstallParams有三个子类,分别是FileInstallArgs,AsecInstallArgs,MoveInsteaaArgs
            //FileInstallArgs用于安装到内部存储(Data分区)
            //AsecInstallArgs用于安装到ASEC(SD卡)
            //MoveInsteaaArgs用于处理已安装的APK的移动逻辑
            final InstallArgs args = createInstallArgs(this);//3
            mArgs = args;
            if (ret == PackageManager.INSTALL_SUCCEEDED) {
                   ...
                if (!origin.existing && requiredUid != -1
                        && isVerificationEnabled(
                              verifierUser.getIdentifier(), installFlags, installerUid)) {
                      ...
                } else{
                	//复制APK到特定的地址
                    ret = args.copyApk(mContainerService, true);
                }
            }
            mRet = ret;
      }

APK安装:

  private void processPendingInstall(final InstallArgs args, final int currentStatus) {
        mHandler.post(new Runnable() {
            public void run() {
                mHandler.removeCallbacks(this);
                PackageInstalledInfo res = new PackageInstalledInfo();
                res.setReturnCode(currentStatus);
                res.uid = -1;
                res.pkg = null;
                res.removedInfo = null;
                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
                    //安装前处理
                    args.doPreInstall(res.returnCode);
                    synchronized (mInstallLock) {
                    	//安装的具体过程
                        installPackageTracedLI(args, res);
                    }
                    //安装后收尾
                    args.doPostInstall(res.returnCode, res.uid);
                }
              ...
            }
        });
    }

PackageManagerService.installPackageLI()方法:

private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
    PackageParser pp = new PackageParser();
    pp.setSeparateProcesses(mSeparateProcesses);
    pp.setDisplayMetrics(mMetrics);
    pp.setCallback(mPackageParserCallback);
    final PackageParser.Package pkg;
    try {
        //解析APK,解析过程会在后面具体描述
        pkg = pp.parsePackage(tmpPackageFile, parseFlags);
    } catch (PackageParserException e) {
     
    }
    ...
    pp = null;
    String oldCodePath = null;
    boolean systemApp = false;
    synchronized (mPackages) {
        // 检查APK是否已经存在,用来确认需要替换APK,还是使用全新的APK安装
        if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
            String oldName = mSettings.getRenamedPackageLPr(pkgName);//获取没被改名前的包名
            if (pkg.mOriginalPackages != null
                    && pkg.mOriginalPackages.contains(oldName)
                    && mPackages.containsKey(oldName)) {
                pkg.setPackageName(oldName);//2
                pkgName = pkg.packageName;
                replace = true;//设置标志位表示是替换安装
            } 
            ...
        }
        PackageSetting ps = mSettings.mPackages.get(pkgName);
        //查看Settings中是否存有要安装的APK的信息,如果有就获取签名信息
        if (ps != null) {
            PackageSetting signatureCheckPs = ps;
            if (pkg.applicationInfo.isStaticSharedLibrary()) {
                SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
                if (libraryEntry != null) {
                    signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
                }
            }
            //APK签名校验
            if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
                if (!checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
                    res.setError("xxx");
                    return;
                }
            } 
            ...
        }

        int N = pkg.permissions.size();
        for (int i = N-1; i >= 0; i--) {
           //遍历每个权限,对权限进行处理
            PackageParser.Permission perm = pkg.permissions.get(i);
            BasePermission bp = mSettings.mPermissions.get(perm.info.name);
         
            }
        }
    }
    if (systemApp) {
        if (onExternal) {
            //系统APP不能在SD卡上替换安装
            res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
                    "Cannot install updates to system apps on sdcard");
            return;
        } else if (instantApp) {
            //系统APP不能被Instant App替换
            res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
                    "Cannot update a system app with an instant app");
            return;
        }
    }
    ...
    //重命名临时文件
    //新的APK包会在名字后面添加1作为ID,每次升级这个数字都会+1
    if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
        res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
        return;
    }

    startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);

    try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
            "installPackageLI")) {
        if (replace) {
         	//替换安装   
            replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
                    installerPackageName, res, args.installReason);
        } else {
        	//安装新的APK
            installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
                    args.user, installerPackageName, volumeUuid, res, args.installReason);
        }
    }

    synchronized (mPackages) {
        final PackageSetting ps = mSettings.mPackages.get(pkgName);
        if (ps != null) {
            //更新应用程序所属的用户
            res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
            ps.setUpdateAvailable(false /*updateAvailable*/);
        }
        ...
    }
}

安装全新的APK:

 private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
            int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
            PackageInstalledInfo res, int installReason) {
        ...
        try {
            //扫描APK,将APK的信息存储在PackageParser.Package类型的newPackage中;
            //一个Package的信息包含了1个base APK以及0个或者多个split APK。
            PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
                    System.currentTimeMillis(), user);
            //更新Settings信息
            updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
                //安装成功后,为新安装的应用程序准备数据
                prepareAppDataAfterInstallLIF(newPackage);

            } else {
                //安装失败则删除APK
                deletePackageLIF(pkgName, UserHandle.ALL, false, null,
                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
            }
        } catch (PackageManagerException e) {
            res.setError("Package couldn't be installed in " + pkg.codePath, e);
        }
        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}

APK的解析过程:

 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()) {		//packageFile是一个目录,说明这是一个Mutiple APK
            parsed = parseClusterPackage(packageFile, flags);
        } else {
            parsed = parseMonolithicPackage(packageFile, flags);
        }
        cacheResult(packageFile, flags, parsed);
        return parsed;
}

解析Mutiple APK:

private Package parseClusterPackage(File packageDir, int flags) throws PackageParserException {
		//解析APK目录
	    final PackageLite lite = parseClusterPackageLite(packageDir, 0);
	    //mOnlyCoreApps = 是否只解析核心APK
	    //lite.coreApp = 当前包是否包含核心应用
        if (mOnlyCoreApps && !lite.coreApp) {	
            throw new PackageParserException(INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
                    "Not a coreApp: " + packageDir);
        }
        ...
        try {
            final AssetManager assets = assetLoader.getBaseAssetManager();
            final File baseApk = new File(lite.baseCodePath);
            //解析BaseAPK
            final Package pkg = parseBaseApk(baseApk, assets, flags);
            if (pkg == null) {
                throw new PackageParserException(INSTALL_PARSE_FAILED_NOT_APK,
                        "Failed to parse base APK: " + baseApk);
            }
            if (!ArrayUtils.isEmpty(lite.splitNames)) {
            	//获取APK分包的数量	
                final int num = lite.splitNames.length;
                pkg.splitNames = lite.splitNames;
                pkg.splitCodePaths = lite.splitCodePaths;
                pkg.splitRevisionCodes = lite.splitRevisionCodes;
                pkg.splitFlags = new int[num];
                pkg.splitPrivateFlags = new int[num];
                pkg.applicationInfo.splitNames = pkg.splitNames;
                pkg.applicationInfo.splitDependencies = splitDependencies;
                //依次解析每个其他APK文件
                for (int i = 0; i < num; i++) {
                    final AssetManager splitAssets = assetLoader.getSplitAssetManager(i);
                    parseSplitApk(pkg, i, splitAssets, flags);
                }
            }
            pkg.setCodePath(packageDir.getAbsolutePath());
            pkg.setUse32bitAbi(lite.use32bitAbi);
            return pkg;
        } finally {
            IoUtils.closeQuietly(assetLoader);
        }
    }

PackageParser.parseBaseApk方法解析BaseAPK:

 private Package parseBaseApk(String apkPath, Resources res, XmlResourceParser parser, int flags,
            String[] outError) throws XmlPullParserException, IOException {
        //创建Package对象,Package对象中包含四大组件的集合,解析之后会将四个组件填写到Package对象中
        final Package pkg = new Package(pkgName);
        //从资源中提取自定义属性集com.android.internal.R.styleable.AndroidManifest得到TypedArray 
        TypedArray sa = res.obtainAttributes(parser,
                com.android.internal.R.styleable.AndroidManifest);//2
        //使用typedarray获取AndroidManifest中的versionCode赋值给Package的对应属性        
        pkg.mVersionCode = pkg.applicationInfo.versionCode = sa.getInteger(
                com.android.internal.R.styleable.AndroidManifest_versionCode, 0);
        pkg.baseRevisionCode = sa.getInteger(
                com.android.internal.R.styleable.AndroidManifest_revisionCode, 0);
        pkg.mVersionName = sa.getNonConfigurationString(
                com.android.internal.R.styleable.AndroidManifest_versionName, 0);
        if (pkg.mVersionName != null) {
            pkg.mVersionName = pkg.mVersionName.intern();
        }
        pkg.coreApp = parser.getAttributeBooleanValue(null, "coreApp", false);//3
        //获取资源后要回收
        sa.recycle();
        //主要用来解析APK的AndroidManifest中的各个标签,比如application、permission、uses-sdk、feature-group等等
        return parseBaseApkCommon(pkg, null, res, parser, flags, outError);
    }

解析四大组件:

  private boolean parseBaseApplication(Package owner, Resources res,
            XmlResourceParser parser, int flags, String[] outError)
        throws XmlPullParserException, IOException {
        ...
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
                continue;
            }
            String tagName = parser.getName();
            if (tagName.equals("activity")) {				//解析activity标签
                Activity a = parseActivity(owner, res, parser, flags, outError, false,
                        owner.baseHardwareAccelerated);		//解析activity标签并得到一个Activity对象
                if (a == null) {
                    mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                    return false;
                }
                owner.activities.add(a);				//将解析得到的Activity对象保存在Package的列表activities中
            } else if (tagName.equals("receiver")) {
                Activity a = parseActivity(owner, res, parser, flags, outError, true, false);
                if (a == null) {
                    mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                    return false;
                }
                owner.receivers.add(a);
            } else if (tagName.equals("service")) {
                Service s = parseService(owner, res, parser, flags, outError);
                if (s == null) {
                    mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                    return false;
                }
                owner.services.add(s);
            } else if (tagName.equals("provider")) {
                Provider p = parseProvider(owner, res, parser, flags, outError);
                if (p == null) {
                    mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                    return false;
                }
                owner.providers.add(p);
            } 
        }
}

Package数据结构:

public final static class Package implements Parcelable {
    public String packageName;
    public String manifestPackageName;
    public String[] splitNames;
    public String volumeUuid;
    public String codePath;
    public String baseCodePath;
    ...
    public ApplicationInfo applicationInfo = new ApplicationInfo();
    public final ArrayList<Permission> permissions = new ArrayList<Permission>(0);
    public final ArrayList<PermissionGroup> permissionGroups = new ArrayList<PermissionGroup>(0);
    public final ArrayList<Activity> activities = new ArrayList<Activity>(0);//1
    public final ArrayList<Activity> receivers = new ArrayList<Activity>(0);
    public final ArrayList<Provider> providers = new ArrayList<Provider>(0);
    public final ArrayList<Service> services = new ArrayList<Service>(0);
    public final ArrayList<Instrumentation> instrumentation = new ArrayList<Instrumentation>(0);
}

这里的Activity,Provider,Permission是PackageParser的静态内部类,它们都继承基类Component,解析的结果会产生一个Package对象,里面的成员代表了这个APK中包含了哪些组件

参考:
https://blog.csdn.net/itachi85/article/details/81321138
https://blog.csdn.net/itachi85/article/details/84311559

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值