Android 应用安装过程

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.系统应用安装:开机时完成,没有安装界面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值