1. 程式人生 > >【筆記】adb install 安裝流程

【筆記】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訊息,處理下一個安裝請求;