1.點擊安裝:
1 . 發送Intent(Intent.ACTION_VIEW)
2 . /package/app/PackageInstaller/ 中的PackageInstallActivity 響應這個Intent
PKMS 中的流程:
PackageManager.installPackage
1.->PKMS.installPackage
2.->PKMS.installPackageAsUser
--(1) 傳下userId,所以可以檢查當前user 在當前進程下是否有安裝權限
--(2) 檢查進程的callingUid 爲SHELL_UID 或者ROOT_UID ,就是adb 上安裝的,會添加PackageManager.INSTALL_FROM_ADB 的標誌位
--(3) new 一個InstallParams對象(後續apk安裝流程就以這個對象爲處理單位),installFlags 傳進去
--(4) 創建一個“INIT_COPY”的msg,攜帶InstallParams對象 ,發送到PackageHandler 來處理
3.-> PackageHandler.INIT_COPY
--處理INIT_COPY消息: 主要就是處理DefaultContainerService 這個服務,這個服務的主要作用就是後續apk 源文件的一些copy操作需要以來它
--(1) 調用connectToService去綁定DefaultContainerService
--(2) 把之前傳下來的InstallParams 放到mPendingInstalls 這個ArrayList 中,它是專門存放需要安裝的APK 的InstallParams的數組
4.-> PackageHandler.sendMsg(MCS_BOUND)
5.-> PackageHandler.MCS_BOUND
6.-> PKMS.mPendingInstalls[0].startCopy()
-- >嘗試調用 4 次 HandlerParams.handleStartCopy()
-- (1).主要通過DefaultContainerService的服務來處理apk 源文件的複製相關,空間是否足夠,路徑合法等
-- (2).創建InstallArgs對象,調用InstallArgs.copyApk()
-- (3).DefaultContainerService.copyPackage 把apk原始文件copy 到 /data/app 下, 且命名爲“base.apk”
--> 調用HandleParams.handleReturnCode()
-- (1) .通過Handler post 一個消息,異步處理
-- (2) .此異步消息中調用installPackageLI()
(2.1) : 加上SCAN_NEW_INSTALL 的flags ,後續scanPackageDirtyLI () 中會根據這個標誌爲來判斷是否需要dex優化:
------- 1.因爲開機流程中中是 scaDirLI-->scanPackageDirtyLI ,所以正常開機時是不會進行dex優化的;
------- 2.第一次開機時進行掃描會加上 force_dex 的flags,PKMS 初始化時就會強制進行掃描;
(2.2) : 此函數中會調用PackageParser.parsePackage() , 主要就是解析apk 的AndroidManifest.xml 中的信息,生成一個PackageParser.package 對象:
------- 1.PKMS 中,各個pkg 對應的信息都是 PackageParser.package 這個類進行記錄的,後續apk信息相關的處理,就是對pkg對應的PackageParser.package 對象 的處理>
------- 2.調用PackageDexOptimizer 進行dex文件的優化相關操作()
7.-->PKMS.scanPackageDirtyLI()
--(1) . activity,service , permission 相關
--(2) . forceDex 和 SCAN_NEW_INSTALL 這兩個flags 處理是否需要dex
8 .--> PackageHandler.msg(POST_INSTALL)
發送ACTION_PACKAGE_ADDED廣播,launcher 等通知pkg狀態更新;