下载安装可分为两部分:拷贝应用和安装应用。拷贝过程的函数调用时序图如图2所示

下载安装

frameworks层的入口函数为PackageManager.installPackage,由应用市场APP调用,然后调用PMS.installPackageAsUser,然后发送消息INIT_COPY、MCS_BOUND开始复制,调用HandlerParams.startCopy。这个方法主要分两部分,一部分是拷贝应用的执行程序,另一部分是创建应用的数据目录,拷贝部分由handleStartCopy完成。之后调用handlerReturnCode来处理创建数据目录。拷贝部分会调用DefaultContainerService来完成,该服务为那些可能位于可删除空间上的文件提供检查和拷贝功能。当底层设置被移除时,这样设计可以防止系统进程保留打开的文件时,不被内核杀死。

handleStartcopy实现在PMS内部类InstallParams中,它的功能是调用远程方法获取包信息和安装位置,下面我们结合关键代码做进一步分析。

@Override    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,            int installFlags, String installerPackageName, int userId) {        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);        final int callingUid = Binder.getCallingUid();//确认权限        enforceCrossUserPermission(callingUid, userId,                true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");//adb安装        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {            installFlags |= PackageManager.INSTALL_FROM_ADB;        } else {            // Caller holds INSTALL_PACKAGES permission, so we're less strict            // about installerPackageName.            installFlags &= ~PackageManager.INSTALL_FROM_ADB;            installFlags &= ~PackageManager.INSTALL_ALL_USERS;        }        UserHandle user;//所有用户        if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {            user = UserHandle.ALL;        } else {            user = new UserHandle(userId);        }        // Only system components can circumvent runtime permissions when installing.//权限校验        if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0                && mContext.checkCallingOrSelfPermission(Manifest.permission                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {            throw new SecurityException("You need the "                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");        }        if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0                || (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {            throw new IllegalArgumentException(                    "New installs into ASEC containers no longer supported");        }        final File originFile = new File(originPath);        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);        final Message msg = mHandler.obtainMessage(INIT_COPY);        params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));        msg.obj = params;//发送拷贝的消息        mHandler.sendMessage(msg);    }

接收消息

//PackageHandler.doHandleMessage void doHandleMessage(Message msg) {            switch (msg.what) {                case INIT_COPY: {                    HandlerParams params = (HandlerParams) msg.obj;                    int idx = mPendingInstalls.size();                    if (!mBound) {                        //连接服务,当服务绑定好之后,会在发一个MCS_BOUND消息                        if (!connectToService()) {                            Slog.e(TAG, "Failed to bind to media container service");                            params.serviceError();                            if (params.traceMethod != null) {                            }                            return;                        } else {                            添加到任务队列                            mPendingInstalls.add(idx, params);                        }                    } else {                        mPendingInstalls.add(idx, params);                        if (idx == 0) {                            //发送一个已经绑定的消息                            mHandler.sendEmptyMessage(MCS_BOUND);                        }                    }                    break;                }

接收MCS_BOUND消息

//PackageHandler.doHandleMessagecase MCS_BOUND: {                    if (msg.obj != null) {                        //获取服务                        mContainerService = (IMediaContainerService) msg.obj;                    }                    if (mContainerService == null) {                        //如果没有绑定清空队列                        if (!mBound) {                            for (HandlerParams params : mPendingInstalls) {                                params.serviceError();                                return;                            }                            mPendingInstalls.clear();                        }                     } else if (mPendingInstalls.size() > 0) {                        HandlerParams params = mPendingInstalls.get(0);                        if (params != null) {                            //调用startCopy                            if (params.startCopy()) {                                if (mPendingInstalls.size() > 0) {                                    mPendingInstalls.remove(0);                                }                                if (mPendingInstalls.size() == 0) {                                    if (mBound) {                                        removeMessages(MCS_UNBIND);                                        Message ubmsg = obtainMessage(MCS_UNBIND);                                        sendMessageDelayed(ubmsg, 10000);                                    }                                } else {                                    mHandler.sendEmptyMessage(MCS_BOUND);                                }                            }                        }                    }                     break;                }

获取HandlerParams 并调用startCopy

// [InstallParams.startCopy] final boolean startCopy() {            boolean res;            try {                               if (++mRetries > MAX_RETRIES) {                    mHandler.sendEmptyMessage(MCS_GIVE_UP);                    handleServiceError();                    return false;                } else {                    handleStartCopy();                    res = true;                }            } catch (RemoteException e) {                mHandler.sendEmptyMessage(MCS_RECONNECT);                res = false;            }            handleReturnCode();            return res;        }

尝试处理4次,如果成功调用handleReturnCode,否则返回错误。

接下来进入InstallParams.handleStartCopy方法看一下。

// [InstallParams.handleStartCopy]public void handleStartCopy() throws RemoteException {            int ret = PackageManager.INSTALL_SUCCEEDED;            // 首先检查文件和cid是否已生成,如生成则设置installFlags。            if (origin.staged) {                if (origin.file != null) {                    installFlags |= PackageManager.INSTALL_INTERNAL;                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;                } else if (origin.cid != null) {                    installFlags |= PackageManager.INSTALL_EXTERNAL;                    installFlags &= ~PackageManager.INSTALL_INTERNAL;                } else {                    throw new IllegalStateException("Invalid stage location");                }            }//在sd卡            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;//在内部存储            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;//免安装app            final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;            PackageInfoLite pkgLite = null;            if (onInt && onSd) {                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;            } else if (onSd && ephemeral) {                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;            } else {                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,                        packageAbiOverride);                /*                 *  然后检查空间大小,如果空间不够则释放无用空间。                 */                if (!origin.staged && pkgLite.recommendedInstallLocation                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {                    // TODO: 集中释放目标设备上的磁盘空间                    final StorageManager storage = StorageManager.from(mContext);//最小临界值                    final long lowThreshold = storage.getStorageLowBytes(                            Environment.getDataDirectory());//计算所需空间的大小                    final long sizeBytes = mContainerService.calculateInstalledSize(                            origin.resolvedPath, isForwardLocked(), packageAbiOverride);                    try {//释放缓存                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);//获取轻量级的包信息                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,                                installFlags, packageAbiOverride);                    } catch (InstallerException e) {                        Slog.w(TAG, "Failed to free cache", e);                    }                        }            }//覆盖原有安装位置的文件,并根据返回结果来确定函数的返回值,并设置installFlags。            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 if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;                } else {                    // 更具安装策略获取安装位置                    loc = installLocationPolicy(pkgLite);                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;                    } else if (!onSd && !onInt) {                        // Override install location with flags                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {                            // Set the flag to install on external media.                            installFlags |= PackageManager.INSTALL_EXTERNAL;                            installFlags &= ~PackageManager.INSTALL_INTERNAL;                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {                            if (DEBUG_EPHEMERAL) {                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");                            }                            installFlags |= PackageManager.INSTALL_INSTANT_APP;                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL                                    |PackageManager.INSTALL_INTERNAL);                        } else {                            // Make sure the flag for installing on external                            // media is unset                            installFlags |= PackageManager.INSTALL_INTERNAL;                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;                        }                    }                }            }//创建安装参数            final InstallArgs args = createInstallArgs(this);            mArgs = args;            if (ret == PackageManager.INSTALL_SUCCEEDED) {                //确定我们是否安装了包验证器。如果我们这样做,那么我们将遵从他们来验证软件包。                final int requiredUid = mRequiredVerifierPackage == null ? -1                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,                                verifierUser.getIdentifier());                final int installerUid =                        verificationInfo == null ? -1 : verificationInfo.installerUid;....省略包验证,一般安装不走这个流程....确定是否有任何已安装的包验证器,如有,则延迟检测。主要分三步:首先新建一个验证Intent,然后设置相关的信息,之后获取验证器列表,最后向每个验证器发送验证Intent。                    /*                      *没有启用包验证,因此立即启动远程调用,使用临时文件初始化复制。                     */                  ret = args.copyApk(mContainerService, true);            }            mRet = ret;        }

向验证器客户端发送intent,只有当验证成功之后才会开启copy工作。如果没有任何验证器则直接拷贝。

接着调用InstallArgs.copyApk方法,手机内部存储安装子类为FileInstallArgs

//FileInstallArgs.copyApkint copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {                       try {                return doCopyApk(imcs, temp);            } finally {                            }}////FileInstallArgs.doCopyApkprivate int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { //如果已经确定位置直接返回if (origin.staged) {codeFile = origin.file;resourceFile = origin.file;return PackageManager.INSTALL_SUCCEEDED;}try {final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;//创建临时目录final File tempDir =mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);codeFile = tempDir;resourceFile = tempDir;} catch (IOException e) {Slog.w(TAG, "Failed to create copy file: " + e);return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;}final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {@Overridepublic ParcelFileDescriptor open(String name, int mode) throws RemoteException {if (!FileUtils.isValidExtFilename(name)) {throw new IllegalArgumentException("Invalid filename: " + name);}try {final File file = new File(codeFile, name);final FileDescriptor fd = Os.open(file.getAbsolutePath(),O_RDWR | O_CREAT, 0644);Os.chmod(file.getAbsolutePath(), 0644);return new ParcelFileDescriptor(fd);} catch (ErrnoException e) {throw new RemoteException("Failed to open: " + e.getMessage());}}};int ret = PackageManager.INSTALL_SUCCEEDED;//从把原始包拷贝到data\app\临时目录下面ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);if (ret != PackageManager.INSTALL_SUCCEEDED) {Slog.e(TAG, "Failed to copy package");return ret;}final File libraryRoot = new File(codeFile, LIB_DIR_NAME);NativeLibraryHelper.Handle handle = null;try {handle = NativeLibraryHelper.Handle.create(codeFile);//拷贝native库ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,abiOverride);} catch (IOException e) {Slog.e(TAG, "Copying native libraries failed", e);ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;} finally {IoUtils.closeQuietly(handle);}return ret;}

跨进程调用,防止阻塞当前进程

//DefaultContainerService.copyPackage//1@Overridepublic int copyPackage(String packagePath, IParcelFileDescriptorFactory target) {if (packagePath == null || target == null) {return PackageManager.INSTALL_FAILED_INVALID_URI;}PackageLite pkg = null;try {final File packageFile = new File(packagePath);//解析轻量级包//内部调用copyPackageInnerpkg = PackageParser.parsePackageLite(packageFile, 0);return copyPackageInner(pkg, target);} catch (PackageParserException | IOException | RemoteException e) {Slog.w(TAG, "Failed to copy package at " + packagePath + ": " + e);return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;}}//2private int copyPackageInner(PackageLite pkg, IParcelFileDescriptorFactory target)throws IOException, RemoteException {    //拷贝文件copyFile(pkg.baseCodePath, target, "base.apk");if (!ArrayUtils.isEmpty(pkg.splitNames)) {for (int i = 0; i < pkg.splitNames.length; i++) {copyFile(pkg.splitCodePaths[i], target, "split_" + pkg.splitNames[i] + ".apk");}}return PackageManager.INSTALL_SUCCEEDED;}//3private void copyFile(String sourcePath, IParcelFileDescriptorFactory target, String targetName)throws IOException, RemoteException {Slog.d(TAG, "Copying " + sourcePath + " to " + targetName);InputStream in = null;OutputStream out = null;try {in = new FileInputStream(sourcePath);out = new ParcelFileDescriptor.AutoCloseOutputStream(target.open(targetName, ParcelFileDescriptor.MODE_READ_WRITE));//拷贝Streams.copy(in, out);} finally {IoUtils.closeQuietly(out);IoUtils.closeQuietly(in);}}

拷贝工作已经完成,接下来就到安装流程了、

//InstallParams.handleReturnCode @Override        void handleReturnCode() {            // 当mArgs 不为空在走processPendingInstall            if (mArgs != null) {                processPendingInstall(mArgs, mRet);            }        }

下面为安装过程入口是PMS.processPendingInstall方法,调用时序图

【下载安装-安装过程图】

//PMS.processPendingInstallprivate 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);}if (!doRestore) {//发送关于安装状态的广播,然后处理安装完的事情,比如打印错误信息,清除临时文件等。Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);mHandler.sendMessage(msg);}}});}//PMS.installPackageTracedLIprivate void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {        try {                installPackageLI(args, res);        } finally {        }}

installPackageLI是安装过程的核心方法,然后调用installPackageLI.首先检查安装包的完整性并解析安装包。

PMS.installPackageLIprivate void installPackageLI(InstallArgs args, PackageInstalledInfo res) {final int installFlags = args.installFlags;final String installerPackageName = args.installerPackageName;final String volumeUuid = args.volumeUuid;final File tmpPackageFile = new File(args.getCodePath());final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)|| (args.volumeUuid != null));final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);final boolean virtualPreload =((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);boolean replace = false;int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;if (args.move != null) {// moving a complete application; perform an initial scan on the new install locationscanFlags |= SCAN_INITIAL;}if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {scanFlags |= SCAN_DONT_KILL_APP;}if (instantApp) {scanFlags |= SCAN_AS_INSTANT_APP;}if (fullApp) {scanFlags |= SCAN_AS_FULL_APP;}if (virtualPreload) {scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;}// Result object to be returnedres.setReturnCode(PackageManager.INSTALL_SUCCEEDED);res.installerPackageName = installerPackageName;if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);// 合理性检查if (instantApp && (forwardLocked || onExternal)) {Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked+ " external=" + onExternal);res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);return;}// 检索包集和解析包final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY| PackageParser.PARSE_ENFORCE_CODE| (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)| (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)| (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0)| (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);PackageParser pp = new PackageParser();pp.setSeparateProcesses(mSeparateProcesses);pp.setDisplayMetrics(mMetrics);pp.setCallback(mPackageParserCallback);Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");final PackageParser.Package pkg;try {//解析安装包,主要对Android清单文件的解析pkg = pp.parsePackage(tmpPackageFile, parseFlags);} catch (PackageParserException e) {res.setError("Failed parse during installPackageLI", e);return;} finally {Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);}

检查SDK版本和沙箱版本,同时检查是否有静态共享库,如有则需要放在内部存储中。

//[PMS.installPackageLI] //检查SDK版本和沙箱版本if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {Slog.w(TAG, "Instant app package " + pkg.packageName + " does not target O");res.setError(INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,"Instant app package must target O");return;}if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) {Slog.w(TAG, "Instant app package " + pkg.packageName+ " does not target targetSandboxVersion 2");res.setError(INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,"Instant app package must use targetSanboxVersion 2");return;}//检查是否有静态共享库if (pkg.applicationInfo.isStaticSharedLibrary()) {// Static shared libraries have synthetic package namesrenameStaticSharedLibraryPackage(pkg);// No static shared libs on external storageif (onExternal) {Slog.i(TAG, "Static shared libs can only be installed on internal storage.");res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,"Packages declaring static-shared libs cannot be updated");return;}}

检查是否有子安装包,如有则子安装包也需要检测。

//[PMS.installPackageLI] // 检查是否有子安装包,如有则子安装包也需要检测。if (pkg.childPackages != null) {synchronized (mPackages) {final int childCount = pkg.childPackages.size();for (int i = 0; i < childCount; i++) {PackageParser.Package childPkg = pkg.childPackages.get(i);PackageInstalledInfo childRes = new PackageInstalledInfo();childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);childRes.pkg = childPkg;childRes.name = childPkg.packageName;PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);if (childPs != null) {childRes.origUsers = childPs.queryInstalledUsers(sUserManager.getUserIds(), true);}if ((mPackages.containsKey(childPkg.packageName))) {childRes.removedInfo = new PackageRemovedInfo(this);childRes.removedInfo.removedPackage = childPkg.packageName;childRes.removedInfo.installerPackageName = childPs.installerPackageName;}if (res.addedChildPackages == null) {res.addedChildPackages = new ArrayMap<>();}res.addedChildPackages.put(childPkg.packageName, childRes);}}}
  •  检查安装包是否已存在,如已存在则需要检查旧的父包、沙箱、sdk等是否已为空,否则会报错。
  •  校验安装包签名
//[PMS.installPackageLI]PackageSetting ps = mSettings.mPackages.get(pkgName);if (ps != null) {PackageSetting signatureCheckPs = ps;if (pkg.applicationInfo.isStaticSharedLibrary()) {SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);if (libraryEntry != null) {signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);}}if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {if (!checkUpgradeKeySetLP(signatureCheckPs, pkg)) {res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "+ pkg.packageName + " upgrade keys do not match the "+ "previously installed version");return;}} else {try {verifySignaturesLP(signatureCheckPs, pkg);} catch (PackageManagerException e) {res.setError(e.error, e.getMessage());return;}}oldCodePath = mSettings.mPackages.get(pkgName).codePathString;if (ps.pkg != null && ps.pkg.applicationInfo != null) {systemApp = (ps.pkg.applicationInfo.flags &ApplicationInfo.FLAG_SYSTEM) != 0;}res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);}

 如果这是一个系统应用,则检查是否在外部存储上或是是否被其他应用替换等 

//[PMS.installPackageLI]if (systemApp) {if (onExternal) {//中止更新;系统app不能被sdcard上的app替换res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,"Cannot install updates to system apps on sdcard");return;} else if (instantApp) {// 中止更新;系统应用程序不能被即时应用程序取代res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,"Cannot update a system app with an instant app");return;}}if (args.move != null) {// 我们做了原地移动,所以dex准备好了scanFlags |= SCAN_NO_DEX;scanFlags |= SCAN_MOVE;synchronized (mPackages) {final PackageSetting ps = mSettings.mPackages.get(pkgName);if (ps == null) {res.setError(INSTALL_FAILED_INTERNAL_ERROR,"Missing settings for moved package " + pkgName);}//我们按原样移动了整个应用程序,因此引入了以前派生的ABI信息。pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;}} else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {// 启用SCAN_NO_DEX标志可以在稍后跳过dexoptscanFlags |= SCAN_NO_DEX;try {String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?args.abiOverride : pkg.cpuAbiOverride);final boolean extractNativeLibs = !pkg.isLibrary();derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,extractNativeLibs, mAppLib32InstallDir);} catch (PackageManagerException pme) {Slog.e(TAG, "Error deriving application ABI", pme);res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");return;}// 包的共享库需要更新。synchronized (mPackages) {try {updateSharedLibrariesLPr(pkg, null);} catch (PackageManagerException e) {Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());}}}    //把临时路径安装base64加密重命名if (!args.doRename(res.returnCode, pkg, oldCodePath)) {res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");return;}if (!instantApp) {startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);} else {if (DEBUG_DOMAIN_VERIFICATION) {Slog.d(TAG, "Not verifying instant app install for app links: " + pkgName);}}

 替换安装:其主要过程为更新设置,清除原有的某些APP数据,重新生成相关的app数据目录等步骤,同时要区分系统应用替换和非系统应用替换。而安装新包:则直接更新设置,生成APP数据即可。

//[PMS.installPackageLI]//冻结安装包try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,"installPackageLI")) {        //替换安装if (replace) {if (pkg.applicationInfo.isStaticSharedLibrary()) {PackageParser.Package existingPkg = mPackages.get(pkg.packageName);if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) {res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "+ "static-shared libs cannot be updated");return;}}            //replacePackageLIFreplacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,installerPackageName, res, args.installReason);} else {            //安装新包installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,args.user, installerPackageName, volumeUuid, res, args.installReason);}}

如有必要,优化dex文件 

//[PMS.installPackageLI]final boolean performDexopt = (res.returnCode == PackageManager.INSTALL_SUCCEEDED)&& !forwardLocked&& !pkg.applicationInfo.isExternalAsec()&& (!instantApp || Global.getInt(mContext.getContentResolver(),Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0);    //根据条件是否进行dex优化if (performDexopt) {Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");// Do not run PackageDexOptimizer through the local performDexOpt// method because `pkg` may not be in `mPackages` yet.//// Also, don't fail application installs if the dexopt step fails.DexoptOptions dexoptOptions = new DexoptOptions(pkg.packageName,REASON_INSTALL,DexoptOptions.DEXOPT_BOOT_COMPLETE);mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,null /* instructionSets */,getOrCreateCompilerPackageStats(pkg),mDexManager.getPackageUseInfoOrDefault(pkg.packageName),dexoptOptions);Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);}

先看替换安装的流程,检查安装限制,比如SDK版本,签名的有效性,共享id的检查,普通应用到即时应用的升级,更新删除的内容, 根据需要设置系统/特权标志,更具系统和分系统应用分两步进行。先看系统用。

//PMS.replacePackageLIFprivate void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,UserHandle user, String installerPackageName, PackageInstalledInfo res,int installReason) {final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;final PackageParser.Package oldPackage;final PackageSetting ps;final String pkgName = pkg.packageName;final int[] allUsers;final int[] installedUsers;synchronized(mPackages) {oldPackage = mPackages.get(pkgName);if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);// 不要允许从预发布SDK升级到正式发布的SDKfinal boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion== android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion== android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;if (oldTargetsPreRelease&& !newTargetsPreRelease&& ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {Slog.w(TAG, "Can't install package targeting released sdk");res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);return;}ps = mSettings.mPackages.get(pkgName);// 验证签名是否有效if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {if (!checkUpgradeKeySetLP(ps, pkg)) {res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,"New package not signed by keys specified by upgrade-keysets: "+ pkgName);return;}} else {// 默认为原始签名匹配if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)!= PackageManager.SIGNATURE_MATCH) {res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,"New package has a different signature: " + pkgName);return;}}// 除非升级散列匹配,否则不要允许系统升级if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {byte[] digestBytes = null;try {final MessageDigest digest = MessageDigest.getInstance("SHA-512");updateDigest(digest, new File(pkg.baseCodePath));if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {for (String path : pkg.splitCodePaths) {updateDigest(digest, new File(path));}}digestBytes = digest.digest();} catch (NoSuchAlgorithmException | IOException e) {res.setError(INSTALL_FAILED_INVALID_APK,"Could not compute hash: " + pkgName);return;}if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {res.setError(INSTALL_FAILED_INVALID_APK,"New package fails restrict-update check: " + pkgName);return;}// 保留升级限制pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;}// 检查共享用户id更改String invalidPackageName =getParentOrChildPackageChangedSharedUser(oldPackage, pkg);if (invalidPackageName != null) {res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,"Package " + invalidPackageName + " tried to change user "+ oldPackage.mSharedUserId);return;}// 在回滚的情况下,记住每个用户/配置文件的安装状态allUsers = sUserManager.getUserIds();installedUsers = ps.queryInstalledUsers(allUsers, true);// don't allow an upgrade from full to ephemeralif (isInstantApp) {if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {for (int currentUser : allUsers) {if (!ps.getInstantApp(currentUser)) {// can't downgrade from full to instantSlog.w(TAG, "Can't replace full app with instant app: " + pkgName+ " for user: " + currentUser);res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);return;}}} else if (!ps.getInstantApp(user.getIdentifier())) {// can't downgrade from full to instantSlog.w(TAG, "Can't replace full app with instant app: " + pkgName+ " for user: " + user.getIdentifier());res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);return;}}}// 更新删除的内容res.removedInfo = new PackageRemovedInfo(this);res.removedInfo.uid = oldPackage.applicationInfo.uid;res.removedInfo.removedPackage = oldPackage.packageName;res.removedInfo.installerPackageName = ps.installerPackageName;res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;res.removedInfo.isUpdate = true;res.removedInfo.origUsers = installedUsers;res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);for (int i = 0; i < installedUsers.length; i++) {final int userId = installedUsers[i];res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));}final int childCount = (oldPackage.childPackages != null)? oldPackage.childPackages.size() : 0;for (int i = 0; i < childCount; i++) {boolean childPackageUpdated = false;PackageParser.Package childPkg = oldPackage.childPackages.get(i);final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);if (res.addedChildPackages != null) {PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);if (childRes != null) {childRes.removedInfo.uid = childPkg.applicationInfo.uid;childRes.removedInfo.removedPackage = childPkg.packageName;if (childPs != null) {childRes.removedInfo.installerPackageName = childPs.installerPackageName;}childRes.removedInfo.isUpdate = true;childRes.removedInfo.installReasons = res.removedInfo.installReasons;childPackageUpdated = true;}}if (!childPackageUpdated) {PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);childRemovedRes.removedPackage = childPkg.packageName;if (childPs != null) {childRemovedRes.installerPackageName = childPs.installerPackageName;}childRemovedRes.isUpdate = false;childRemovedRes.dataRemoved = true;synchronized (mPackages) {if (childPs != null) {childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);}}if (res.removedInfo.removedChildPackages == null) {res.removedInfo.removedChildPackages = new ArrayMap<>();}res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);}}boolean sysPkg = (isSystemApp(oldPackage));if (sysPkg) {// 根据需要设置系统/特权标志final boolean privileged =(oldPackage.applicationInfo.privateFlags& ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;final int systemPolicyFlags = policyFlags| PackageParser.PARSE_IS_SYSTEM| (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,user, allUsers, installerPackageName, res, installReason);} else {replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,user, allUsers, installerPackageName, res, installReason);}}

更新系统包的主要是先删除现有的旧包,禁用替换包,清除原来data目录和配置文件,把原来解析出来的包信息保存到PMS里面

scanPackageTracedLI,点击可以查看这个流程。创建data/data/包名/ 目录,更新相关设置。如果安装失败在回滚旧的安装信息。

//PMS.replaceSystemPackageLIF public void replaceSystemPackageLIF(PackageParser.Package deletedPackage,PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,int[] allUsers, String installerPackageName, PackageInstalledInfo res,int installReason) {final boolean disabledSystem;// 删除现有系统包removePackageLI(deletedPackage, true);synchronized (mPackages) {disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);}if (!disabledSystem) {//我们不需要禁用当前系统包中的.apk,这意味着我们将替换已经安装的另一个更新。我们需要确保删除了老的。res.removedInfo.args = createInstallArgsForExisting(0,deletedPackage.applicationInfo.getCodePath(),deletedPackage.applicationInfo.getResourcePath(),getAppDexInstructionSets(deletedPackage.applicationInfo));} else {res.removedInfo.args = null;}// 成功禁用旧的包。现在继续重新安装//清除原来的data目录clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE| StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);//清除原来应用的配置文件clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);PackageParser.Package newPackage = null;try {// 将包添加到内部数据结构中,此处调用请参考初始化安装的流程,这里不做分析。newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);//设置更新和安装时间PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,System.currentTimeMillis());// 如果成功,则更新包的动态状态if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {//既然安装成功了,请确保我们删除了更新删除的子包的数据目录。final int deletedChildCount = (deletedPackage.childPackages != null)? deletedPackage.childPackages.size() : 0;final int newChildCount = (newPackage.childPackages != null)? newPackage.childPackages.size() : 0;for (int i = 0; i < deletedChildCount; i++) {PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);boolean childPackageDeleted = true;for (int j = 0; j < newChildCount; j++) {PackageParser.Package newChildPkg = newPackage.childPackages.get(j);if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {childPackageDeleted = false;break;}}if (childPackageDeleted) {PackageSetting ps = mSettings.getDisabledSystemPkgLPr(deletedChildPkg.packageName);if (ps != null && res.removedInfo.removedChildPackages != null) {PackageRemovedInfo removedChildRes = res.removedInfo.removedChildPackages.get(deletedChildPkg.packageName);removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;}}}//更新设置updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,installReason);//准备data目录prepareAppDataAfterInstallLIF(newPackage);//通知dex优化mDexManager.notifyPackageUpdated(newPackage.packageName,newPackage.baseCodePath, newPackage.splitCodePaths);}} catch (PackageManagerException e) {res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);res.setError("Package couldn't be installed in " + pkg.codePath, e);}if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {// 重新安装失败。恢复旧信息,删除新的pkg信息if (newPackage != null) {removeInstalledPackageLI(newPackage, true);}// 添加回旧的系统包  synchronized (mPackages) {if (disabledSystem) {enableSystemPackageLPw(deletedPackage);}// 确保安装包的名称是最新的setInstallerPackageNameLPw(deletedPackage, installerPackageName);// 更新恢复包的权限updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);//保存包信息到package.xml里面mSettings.writeLPr();}}}

与更新安装系统应用大体相同。

//PMS.replaceNonSystemPackageLIFprivate void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,int[] allUsers, String installerPackageName, PackageInstalledInfo res,int installReason) {String pkgName = deletedPackage.packageName;boolean deletedPkg = true;boolean addedPkg = false;boolean updatedSettings = false;final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;final int deleteFlags = PackageManager.DELETE_KEEP_DATA| (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);final long origUpdateTime = (pkg.mExtras != null)? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;// 首先删除现有的包,同时保留数据目录if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,res.removedInfo, true, pkg)) {//如果现有的包没有被成功删除res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");deletedPkg = false;} else {//成功删除旧包;进行替换。// If deleted package lived in a container, give users a chance to// relinquish resources before killing.if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {if (DEBUG_INSTALL) {Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");}final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };final ArrayList pkgList = new ArrayList(1);pkgList.add(deletedPackage.applicationInfo.packageName);sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);}clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE| StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);try {final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,installReason);// Update the in-memory copy of the previous code paths.PackageSetting ps = mSettings.mPackages.get(pkgName);if (!killApp) {if (ps.oldCodePaths == null) {ps.oldCodePaths = new ArraySet<>();}Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);if (deletedPackage.splitCodePaths != null) {Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);}} else {ps.oldCodePaths = null;}if (ps.childPackageNames != null) {for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {final String childPkgName = ps.childPackageNames.get(i);final PackageSetting childPs = mSettings.mPackages.get(childPkgName);childPs.oldCodePaths = ps.oldCodePaths;}}// 设置即时应用程序状态,但只有在明确指定的情况下final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);prepareAppDataAfterInstallLIF(newPackage);addedPkg = true;mDexManager.notifyPackageUpdated(newPackage.packageName,newPackage.baseCodePath, newPackage.splitCodePaths);} catch (PackageManagerException e) {res.setError("Package couldn't be installed in " + pkg.codePath, e);}}if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);// 为失败的安装恢复所有内部状态变化和添加的文件夹if (addedPkg) {deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,res.removedInfo, true, null);}// Restore the old packageif (deletedPkg) {if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);File restoreFile = new File(deletedPackage.codePath);// 恢复旧包boolean oldExternal = isExternal(deletedPackage);int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |(deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |(oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;try {scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,null);} catch (PackageManagerException e) {Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "+ e.getMessage());return;}synchronized (mPackages) {// 确保安装包的名称是最新的setInstallerPackageNameLPw(deletedPackage, installerPackageName);// 更新恢复包的权限updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);mSettings.writeLPr();}}} else {//安装成功,更新信息synchronized (mPackages) {PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);if (ps != null) {res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;if (res.removedInfo.removedChildPackages != null) {final int childCount = res.removedInfo.removedChildPackages.size();// Iterate in reverse as we may modify the collectionfor (int i = childCount - 1; i >= 0; i--) {String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);if (res.addedChildPackages.containsKey(childPackageName)) {res.removedInfo.removedChildPackages.removeAt(i);} else {PackageRemovedInfo childInfo = res.removedInfo.removedChildPackages.valueAt(i);childInfo.removedForAllUsers = mPackages.get(childInfo.removedPackage) == null;}}}}}}}

接下来看安装一个不存在的新包,流程相对简单。

//PMS.installNewPackageLIF private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,PackageInstalledInfo res, int installReason) {Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");// 请记住这一点,以防我们需要回滚此安装String pkgName = pkg.packageName;synchronized(mPackages) {final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);if (renamedPackage != null) {// 已经安装了同名的包,尽管它已被重命名为较旧的名称。res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName+ " without first uninstalling package running as "+ renamedPackage);return;}if (mPackages.containsKey(pkgName)) {// 不要允许安装在具有相同名称的现有包上。res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName+ " without first uninstalling.");return;}}try {//数据转移流程PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,System.currentTimeMillis(), user);//更新设置updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {//准备应用所需的要数据目录prepareAppDataAfterInstallLIF(newPackage);} else {// 从内部结构中删除包,但保留可能已经存在的任何数据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);}}

   然后为已安装的应用准备数据目录,其依次的顺序是

  • PMS.prepareAppDataAfterInstallLIF
  • PMS.prepareAppDataLIF
  • PMS.prepareAppDataLeafLIF
  • Installer.createAppData

以上为下载安装的流程。其中PackageParser .parsePackage(tmpPackageFile, parseFlags)和scanPackageTracedLI这个两个流程在构造函数初始化安装中已经分析,这里不再赘述。请参考Android PackageManagerService(一)启动流程分析

更多相关文章

  1. Android(安卓)API Demo实例解析
  2. android sensor framework
  3. android 运行时生成dex文件,并装载调用
  4. Android4.4 Camera Gallery 分离
  5. Android之webView入门
  6. Firefox OS 学习——manifest.webapp结构分析
  7. GLSurfaceView 基本使用与源码解析
  8. Android中GUI系统的Event路由机制
  9. 简单的音频播放功能MediaPlayer使用中所遇到的坑。

随机推荐

  1. Android版本号 API level一览表
  2. Android(安卓)GLSurfaceView模糊效果
  3. Android应用程序设置Home Screen
  4. android dialog集合
  5. android获得圆角图片
  6. Android(安卓)Add new target
  7. #android training# Graphics & Animatio
  8. Android(安卓)Getting Started
  9. android SpannableString使用详解
  10. Android(安卓)Linux usb gadget configfs