Android 应用安装过程

来源:互联网 发布:上海聚友网络客服电话 编辑:程序博客网 时间:2024/05/16 13:49

1.网络下载安装:从market安装,没有安装界面
下载完成后,会自动调用Packagemanager的安装方法installPackage(),该方法调用了installPackageAsUser()方法:installPackageAsUser方法如下:

    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, VerificationParams verificationParams, String packageAbiOverride, int userId) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); ..... .....        final File originFile = new File(originPath);        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);        final Message msg = mHandler.obtainMessage(INIT_COPY);        msg.obj = new InstallParams(origin, observer, installFlags, installerPackageName, verificationParams, user, packageAbiOverride);        mHandler.sendMessage(msg);    }

此方法最后调用mHandler.sendMessage(msg);将msg发送给继承Handler的PackageHandler类的HandleMessage()方法.
由于标识为INIT_COPY,代码如下:

    case INIT_COPY: {        HandlerParams params = (HandlerParams) msg.obj;        int idx = mPendingInstalls.size();        if (DEBUG_INSTALL)              Slog.i(TAG, "init_copy idx=" + idx + ": " + params);        // If a bind was already initiated we dont really        // need to do anything. The pending install        // will be processed later on.        if (!mBound) {        // If this is the only one pending we might        // have to bind to the service again.             if (!connectToService()) {                 Slog.e(TAG, "Failed to bind to media container service");                 params.serviceError();                 return;             } else {              // Once we bind to the service, the first              // pending request will be processed.                 mPendingInstalls.add(idx, params);             }       } else {            mPendingInstalls.add(idx, params);            // Already bound to the service. Just make            // sure we trigger off processing the first request.            if (idx == 0) {                mHandler.sendEmptyMessage(MCS_BOUND);            }       }   break;}

代码最后将msg.obj添加到mPendingInstalls列表中,该列表存放着包的安装信息.然后触发第一个安装请求sendEmptyMessage(MCS_BOUND)
MCS_BOUND标识处的代码如下:

     HandlerParams params = mPendingInstalls.get(0);     if (params != null) {          if (params.startCopy()) {          // We are done...  look for more work or to          // go idle.          ...          ...          }

此处获取params后调用startCopy()函数,来完成拷贝和安装,startCopy函数在HandlerParams中为抽象方法,它的实现实在继承该类的InstallParams类中,方法比较复杂,工作流程主要如下:

  1. 检查安装位置标记位是否有冲突,如果有冲突,则安装失败,这里的有冲突是指“一个apk同时要求被安装到内部存储和sd卡”

  2. 调用MCS服务的getMinimalPackageInfo方法来得到apk的推荐安装位置,并检查是否能够进行正常的安装。在这一步,有可能抛出一些无法安装的状态位:存储空间不足、程序已经安装、无效的apk文件等,这个时候安装过程终止

  3. 到这一步,表示程序可以正常安装,同时MCS服务服务可能会根据需要调整安装位置,在InstallParams的installLocationPolicy中完成

  4. 文件的复制过程,PMS针对内部存储和sd卡分别提供了一个类:FileInstallArgs和AsecInstallArgs,并分别调用二者的copyApk方法来完成apk的复制过程

ret = args.copyApk(mContainerService, true);

2.第三方应用安装:通过SD卡里的APK文件安装,有安装界面,由packageinstaller.apk应用处理安装及卸载过程的界面。

3.ADB工具安装:没有安装界面。

4.系统应用安装:开机时完成,没有安装界面

0 0