美文网首页
APK安装原理

APK安装原理

作者: 瑜小贤 | 来源:发表于2019-12-30 16:25 被阅读0次

    基于android 5.0

    • 有界面的安装方式

    PackageInstallerActivity.java

    InstallAppProgress.java

    • 无界面安装 adb_commandline

    int adb_commandline(int argc, char** argv){
      //...
      if(!strcmp(argv[0], "install")){
        if(argc < 2) return usage();
        //调用install_app函数进行处理
        return install_app(ttype, serial, argc, argv);
      }
    }
    
    int install_app(transport_type transport, char* serial, int argc, char** argv){
      static const char *const DATA_DEST = "/data/local/tmp/%s";
      static const char *const SD_DEST = "/sdcard/tmp/%s"
      const char* where = DATA_DEST;
      //...
      int err = do_sync_push(apk_file, apk_dest, 0 /*no show progress*/);//将apk push到目标目录 进行解析安装
      //...
      pm_command(transport, serial, argc, argv);
      //...
    }
    
    static int pm_command(transport_type transport, char* serial, int argc, char** argv){
      char buf[4096];
    
      snpintf(buf, sizeof(buf), "shell:pm"); //指向一个pm脚本文件
    
      //...
      send_shellcommand(transport, serial, buf);
      return 0;
    }
    
    
    

    frameworks/base/cmds/pm/pm

    base=/system
    export CLASSPATH=$base/framework/pm.jar
    exec app_process $base/bin com.android.commands.pm.P "$@"
    

    frameworks/base/cmds/pm 下的工程源码,生成了上文的pm.jar,而工程源码中的唯一java文件是 Pm.java

    public final class Pm{
      //...
      IPackageManager mPm;
      IPackageInstaller mInstaller;
      IUserManager mUm;
      //...
      public static void main(String[] args){
        int exitCode = 1;
        try{
          exitCode = new Pm().run(args);
        } catch(Exception e){
          Log.e(TAG, "Error", e);
          System.err.println("Error:" + e);
          if(e instanceof RemoteException){
            System.err.println(PM_NOT_RUNING_ERR);
          }
        }
        System.exit(exitCode);
      }
    
      public int run(String[] args) throws IOException, RemoteException{
        //...
        mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
        //...
        if("install".equals(op)){
          return runInstall();
        }
        //...
      }
    
      private int runInstall(){
        //...
        try{
          VerificationParams verificationParams = new VerificationParams(verificationURI,
              originatingURI, referrerURI, VerificationParams.NO_UID, null);
          mPm.installPackageAsUser(apkFilePath, obs.getBinder(), installFlags, 
              installerPackageName, verificationParams, abi, userId); //从Pm.java到PackageManagerService中
          //...
        }catch(RemoteException e){
         //...
        }
        //...
      }
      //...
    }
    

    PackageManagerService.java

    public class PackageManagerService extends IPackageManager.Stub{
      //...
      /**
       * bind机制服务端
       *
       * @param originPath 要安装apk的路径
       * @param observer 监听apk安装的结果信息
       * @param installFlags 安装的相关参数
       * @param installerPackageName 安装的包名
       * @param userId userId
      **/
      @Override 
      public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
          int installFlags, String installerPackageName, int userId){
        //...
        //组装消息,发送handler
        final Message msg = mHandler.obtainMessage(INIT_COPY);
        //...
        mHandler.sendMessage(msg);
      }
    
      class PackageHandler extends Handler {
        //...
        void doHandleMessage(Message msg){
          switch(msg.what){
            case INIT_COPY:{
              //...
              mHadnler.sendEmptyMessage(MCS_BOUND);
              //...
              break;
            }
        
            case MCS_BOUND:{
              //...
              if(params.startCopy()){
                //...
              }
              //...
              break;
            }
          }
        }
    
      private abstract class HandlerParams {
        private static final int MAX_RETRIES = 4;
        //...
        final boolean startCopy(){
          boolean res;
          try{
            if(++mRetries > MAX_RETRIES){ //默认尝试安装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;
        }
        //...
        abstract void handleReturnCode();
      }
      //...
    }
    
    无界面安装 Apk安装的原理

    相关文章

      网友评论

          本文标题:APK安装原理

          本文链接:https://www.haomeiwen.com/subject/xgcmoctx.html