日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java apk安装路径_android apk安装过程源码解析

發布時間:2023/12/10 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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安装过程源码解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。