【笔记】adb install 安装流程

1. 应用安装的几种途径:
   1.系统开机的应用安装,安装的是系统级别的应用,用户在没有获取到root权限的情况下无法卸载的应用
   2.adb安装的应用,没有安装界面
   3.第三方市场下载的应用:部分是通过电脑的客户端安装的没有安装的界面,部分是手机上的市场安装的,会有安装的界面。
   
   
   
   
   
   1.1 .开机安装APP:
     1.SystemServer 启动PKMS
        1.SystemServer 中创建installer对象,传入PKMS 的实例中;
        2.创建PKMS 实例时,传入mFactoryTestMode,判断是否是工厂模式?(工厂测试模式下有什么区别???)
        3.创建PKMS 实例时,传入mOnlyCore , 涉及加密流程
        4.此进程完成对 /system/app,/data/app,/system/framework,/data/app-private 下的 apk 文件的解析
     2.AndroidManifest.xml 中记录的packageInfo 信息,实际上和PKMS.getPackageInfo() 的返回值是一一对应的。
       packageInfo 类中包含package 以及包中activity 信息。[类似于AndroidManifest中一层层包含]
       applicationInfo 类对应的就是AndroidManifest.xml 中对应application 下的信息
       activityInfo 类对应的就是AndroidManifest.xml 中对应activity 下的信息

****************************************************************************************************************************
       

2.源码流程解析
       
//https://blog.csdn.net/csdn_of_coder/article/details/74025409


1.adb install --->system/core/adb/commandline.cpp::install_app()
              ... 1.确定2个拷贝文件的位置,默认拷贝到内部
                    
              ... 2.将制定的apk文件从电脑端拷贝到制定的目录处
                    1.安装到data目录下时,会将apk先拷贝一份到"/data/local/tmp/%s"目录下;
              ... 3.执行pm 脚本,调用pm_command()函数开始去安装
              ... 4.当安装结束时删除该apk文件
              ... 5.手机的端的adbd程序接收到客户机发送的shell pm命令后,会开启一个shell去执行pm脚本.
                    1.编译时会被打包成/system/bin/pm可执行程序,执行pm可执行程序其实就是执行这段脚本
                    2.我们传入的是install命令,所以执行runInstall()函数;至此,安装过程就即将进入PackageManagerService了
                    
                    
                    
                    
2.PackageManager::installPackage()函数安装应用:


   PackageManager.installPackage 
   --->ApplicationPackageManager.installPackage
      【ApplicationPackageManager 复写了PackageManager】
   --->PackageManager.PackageInstallObserver
      1.【它是用户用来监听APK安装的最后结果的】 
      2.【当apk安装结束时,系统会回调PackageManager.PackageInstallObserver.onPackageInstalled()接口通知用户当前apk安装的结果信息】
      
   --->PackageManagerService.installPackageAsUser
   
       1.检测权限:UserManager.DISALLOW_INSTALL_APPS ,多用户情况下...
       2.callingUid =Process.SHELL_UID ||callingUid == Process.ROOT_UID  时,增加PM.INSTALL_FROM_ADB的flags...
       3.多用户安装:如果带有INSASLL_ALL_USERS标记,则给所有用户安装
       4.初始化【InstallParams】 对象实例,将安装参数信息保存到InstallParams对象中
          1.final Message msg = mHandler.obtainMessage(INIT_COPY)
          2.final InstallParams params = new InstallParams( ... ...)
          3.msg.obj = params
       5.接着会发送INIT_COPY消息到Handler进行处理
    --->PackageManagerService.PackageHandler【PKMS 中专门处理install相关的handler】
    
        ... case INIT_COPY:
            1.检测是否绑定DefaultContainerService服务;
            2.mPendingInstalls是PackageHandler的一个成员,它保存所有的APK安装的InstallParams【不是直接保存HandlerParams 对象,而是根据HandlerParams生成一个InstallParams,InstallParams 继承HandlerParams并实现了 abstract HandlerParams.handleStartCopy() 函数】对象;
            
        ... case MCS_BOUND:
            1.DefaultContainerService服务连接正常;
            2.从 mPendingInstalls 的首部拿出需要执行的安装参数信息,生成PKMS.HandlerParrams对象实例【mPendingInstalls 是PKMS 的成员变量,它直接包含的也是PKMS 的成员变量HandlerParrams】
            3.调用HandlerParrams接口,去执行apk的拷贝工作;此处是调用HandlerParams::startCopy();【尝试的次数是4次】【每个APK 的安装,都是以HandlerParams对象实例为单位进行的】
            
              --->HandlerParams::startCopy()
              
              --->【InstallParams继承HandlerParams】InstallParams::handleStartCopy()
                   1.进行一些安装标志的判断,检测onSd / onInt ;

                   2.调用DCS::getMinimalPackageInfo()方法获取该apk安装需要的大小及其他信息,信息会封装到PackageInfoLite对象中;检测安装的路径剩余空间,如果不足,尝试去除cache
                   3.以当前的InstallParams为实例,创建【FileInstallArgs对象(FileInstallArgs 是InstallParams 的内部类)】,并保存一份到InstallParams对象的mArgs字段中


              ---> FileInstallArgs::copyApk()
                   1.最终执行apk 文件的copy是DefaultContainerService::copyPackage()方法;

                      DCS:copyPackage

                          ....>调用PackageParser.parsePackageLite 获取PackageLite 对象;

                          ....>DCS.copyPackageInner

                                
                            
              
            4.startCopy工作完成后,【移除】 mPendingInstalls首部内容;
            5.如果mPendingInstalls已经没有内容,说明安装任务已经全部执行完毕,则会延迟10s后断开服务连接  OR  否则,会再次发送MCS_BOUND消息,处理下一个安装请求;

猜你喜欢

转载自blog.csdn.net/pirionFordring/article/details/83416922
今日推荐