java apk安装路径_android apk安装过程源码解析
前言:
前一篇博客分析了一下PackageManagerService是如何解析apk的以及我們如何解析未安裝apk中的androidManifest.xml文件。解析完肯定要安裝的,索性寫一篇關于android系統是如何安裝我們apk的流程分析。不過這里僅僅只分析java層面的代碼,C層方面的就跳過了。
apk安裝起始點-Pm.java run()
apk安裝java層的起始位置是在Pm.java的run()中。
這里有2個重點,第一個紅框可以看到與我們的PackageManagerService有關,獲取PackageManagerService的binder對象,與PackageManagerService進行通信。并且如果這個對象為null 則輸出異常信息直接返回,其實也不難理解,PackageManagerService把我們的apk給掃描了,那安裝應該也會在其中。所以這里可以肯定的是apk的安裝實現就在我們的PackageManagerService中;第二點就是根據這個install標識來執行安裝的方法了。那我們就進入到runInstall()中來看下,它的內部是調用了PackageManagerService的什么方法來進行apk安裝的。
runInstall()
從上面的runInstall()方法的代碼可以看到 有3個標紅框的地方需要了解,第一個obs對象,用于接收PackageManagerService安裝結果,其實從第三個紅框就一目了然的了解INSTALL_SUCCEEDED,安裝成功!就輸出Success;第二個紅框就是通過binder來調起PackageManagerService中的installPackageWithVerificationAndEncryption()方法。
那接下來看下PackageManagerService中的installPackageWithVerificationAndEncryption()方法是如何操作的
這個方法代碼并不是很多,重點在最后一部分,通過handler發送一個INIT_COPY的消息,消息的內容是一個InstallParams對象。(這里要注意下InstallParams,等下會說下這個)
那我們就只要找到handleMessage中處理這個INIT_COPY的消息代碼就行了
這里值得一提的是,安裝apk的操作還需要一個服務,只有這個服務被bind了,才行進行下一步的工作,也就是通過handler繼續發送一個消息。(這個服務是com.android.defcontainer.DefaultContainerService這里就不深層次分析了,它的作用就是用來解析APK,以及獲取推薦安裝路徑的,安裝的路徑與內存情況以及一些標識來決定)
繞來繞去,開啟服務之后又發送了一個消息,那只好繼續看下這個MCS_BOUND消息是如何處理的。
MCS_BOUND:
從代碼中就能明顯看到,這里又對服務進行了一次判斷,是否已經連接,所以這個服務于我們的apk安裝是共存的,其中mPendingInstalls就是用于存儲需要安裝的請求,只有當這個隊列為空時才斷開連接。(在INIT_COPY消息處理中被添加到mPendingInstalls中的),然后又調用了HandlerParams的startCopy()方法執行安裝。
可以看到以下幾個重點
1.HandlerParams是個抽象類
2.箭頭那可以知道,這個安裝會嘗試4次,超過4次就GG了
3.執行handleStartCopy()方法
4.執行handleReturnCode()方法
在這之前值得一提的是前面installPackageWithVerificationAndEncryption()方法中通過handler發送消息,消息的內容是InstallParams,而InstallParams又是繼承自HandlerParams這個抽象類,所以具體執行的是handleStartCopy()與handleReturnCode()的是InstallParams。
不過InstallParams這個方法的代碼很長,這里大致說下,InstallParams的handleStartCopy()的主要內容是通過com.android.defcontainer.DefaultContainerService來獲取apk的推薦安裝路徑,通過這個路徑來確定是內部安裝還是SD卡安裝,并且在這個方法的末尾,根據路徑來創建不同的InstallArgs,分別是FileInstallArgs/SdInstallArgs執行各自的copyApk()方法!
這里就從FileInstallArgs的copyApk()這條路線來分析。
FileInstallArgs.copyApk()
這個方法的重點部分就在紅框位置,它的作用就是把我們的APK給復制到/data/app下,這個的路徑可以通過context.getPackageCodePath()獲取到,命名規則一般都是XXX.base.apk,不過這里是個臨時文件,在安裝的時候會對其進行改名操作。
到這就分析完了InstallParams的handleStartCopy()方法,還有一個重點部分是handleReturnCode方法,所以接著分析handleReturnCode();
handleReturnCode():
這里很簡單,調用了processPendingInstall()方法
processPendingInstall():
這里分為兩部分:
第一張圖可以看到標紅框部分執行了doPreInstall()和installPackageLI(),doPostInstall();
doPreInstall和doPostInstall內部很簡單,他的作用就是把我們安裝過程中的臨時文件刪除,installPackageLI就是我們的正真安裝操作。
第二張圖則是安裝之后,發送一個POST_INTALL消息,告訴系統是否安裝完畢。
一系列的安裝流程終于走到最后了,看下最終的install操作的方法
installPackageLI:
下面兩個紅框可以看到,分別通過兩種不同的方式進行安裝,具體的判斷邏輯是根據包名來判斷的,如果存在包名則是覆蓋安裝,而不存在就是安裝一個新的apk。replacePackageLI()和installNewPackageLI()內部就和掃描系統中的package信息一樣,? 它把APK進行掃描,然后把apk中的信息存儲到PackageManagerService中。了解4大組件的啟動過程就會知道,有一段流程是在PackageManagerService中獲取四大組件信息,這些信息就是通過把我們apk掃描安裝然后存儲到PackageMangerService中的。這樣我們的apk就已經安裝完成了。
圖中還有一個紅框,args.doRename()方法(這個args就是我們的FileInstallArgs),前面提到過我們的apk文件會被復制到/data/app下,當復制進來的時候命名格式不是xx.apk,而這里的doRename()方法就是把這個復制進來的文件改名成XXXbase.apk。所以我們context.getPackageCodePath()獲取到的路徑就是改名后的信息。
APK安裝的源碼分析就分析到這,大致的流程就是獲取我們的安裝位置,然后復制我們的apk文件到特定目錄,然后安裝我們的apk把apk的信息存儲到PackageManagerService中。跟著上面的代碼走一遍,相信還是很好理解的。
總結
以上是生活随笔為你收集整理的java apk安装路径_android apk安装过程源码解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows系统如何修改Hosts文件
- 下一篇: 如何将桌面上的计算机图表隐藏,怎么把电脑