深入安卓Package Manager和Package Installer

hanson發表於2014-05-09

我們每天都在安裝和解除安裝APK(安卓應用程式包檔案),或許一天會有好幾次,但是你有想過下面問題嗎?

  1. 什麼是Package Manager(包管理器)和Package Installer(程式安裝包)?
  2. APK檔案儲存在Android的哪個地方?
  3. APK檔案安裝過程的細節是怎樣的?
  4. Package Manager(包管理器)是怎樣儲存資料的?
  5. 我應該去哪裡找Package Manager和Package Installer的原始碼?

1、什麼是Package Manager和Package Installer

PackageInstaller是安卓上預設的應用程式,用它來互動式地安裝普通包檔案。PackageInstaller提供了使用者介面來管理應用或者包檔案。PackageInstaller呼叫一個叫InstallAppProgress的activity來獲取使用者發出的指令。InstallAppProgress會請求Package Manager服務,然後通過indalld來安裝包檔案。原始碼提供在/packages/apps/PackageInstaller上。

Installd這個系統守護程式的首要角色是獲取來自Package Manager服務的請求,而該請求是通過Linux套接字/dev/socket/installed獲得的。
Installd使用管理員許可權執行一系列的步驟來安裝APK。參考:commands.c

Package Manger是一個實際上管理應用程式安裝、解除安裝和升級的API。當我們安裝APK檔案時,Package Manager會解析APK包檔案和顯示確認資訊。當我們點選OK按鈕後,Package Manger會呼叫一個叫“InstallPackage”的方法,這個方法有四個引數,也就是uri、installFlags、observer和installPackagename。Package Manger會啟動一個叫“package”的service(服務),現在所有模糊的東西會發生在這個service中。你可以在PackageInstaller原始碼中檢視“PackageInstallAcitivity.java”和“InstallAppProgress.java”。Package Manger服務執行在系統服務程式中,而安裝守護程式(installd)作為一個本地程式執行著,他們都在系統啟動時開始執行。

2、APK檔案儲存在Android的哪個地方?

  1. 預裝程式(即相機,日曆和瀏覽器等)儲存在/system/app/中。
  2. 使用者安裝程式(APIDemo,Any.do等)儲存在/data/app/中。
  3. Package Manager建立資料目錄/data/data//來儲存資料庫、shared preference、本地函式庫和快取資料。

你可能會看到apk檔案和同一個APK的*.odex檔案,而ODEX檔案是完全不同的討論和目的了。

3、APK檔案安裝過程的細節是怎樣的?

下面的過程執行在Package Manger服務中。

  • 等待;
  • 新增一個包檔案到安裝程式的佇列中;
  • 確定合適的地方來安裝包檔案;
  • 複製apk檔案到一個給定的目錄下;
  • 確定應用的UID;
  • 請求installd守護程式程式;
  • 建立應用目錄和設定許可權;
  • 提取dex程式碼到快取目錄中;
  • 解析packages.list、system、data和packages.xml的最新狀態;
  • 向系統傳送廣播訊息,訊息帶有安裝完成效果的名字Intent.ACTION_PACKAGE_ADDED:如果是更新,會帶有新的(Intent.ACTION_PACKAGE_REPLACED)。

Package Installer

4、Package Manager(包管理器)是怎樣儲存資料的?

Package Manager儲存應用程式的資訊在/data/system目錄下的三個檔案裡。下面的例子是從Android 4 ICS(Ice Cream Sandwich)模擬器提取出來的圖片。

1. packages.xml:這個檔案包含所有的許可權和Packages/Applications。

這個xml檔案包含兩種資訊,許可權和package(application)。 許可權是儲存在標籤裡的。每個Permission(許可權)有三個屬性,即name、package和protection。Name屬性包含許可權的名字,也就是我們在AndroidManifest.xml所用的,Package屬性表明許可權所屬的包。在大多數情況下,“android”是一個值,因為標籤包含預設的許可權,以及protection表明安全的等級。

package標籤包含10個屬性和一些子標籤。

Sr 屬性 描述
1 name 包名
2 codePath APK檔案安裝路徑(/system/app/ 或 /data/app/)
3 nativeLibraryPath 本地函式庫(*.so檔案),預設路徑/data/data/<package name>/lib/
4 flag 儲存ApplicationInfo標記[http://developer.android.com/reference/android/content/pm/ApplicationInfo.html](http://developer.android.com/reference/android/content/pm/ApplicationInfo.html)
5 ft 十六進位制時間戳timestamp
6 lt 首次安裝十六進位制時間戳
7 ut 最後更新十六進位制時間戳
8 version AndroidManifest.xml檔案中的版本程式碼
[http://developer.android.com/guide/topics/manifest/manifest-element.html#vcode]
9 sharedUserId Linux使用者ID名稱,其他應用可檢視此ID。與在AndroidManifest.xml中的定義一致[http://developer.android.com/guide/topics/manifest/manifest-element.html#uid]
10 userId Linux使用者ID名稱

子標籤

  • sigs 簽名資訊,count屬性代表cert標籤的數量。
  • cert 包含證照的key,index屬性代表證照的全域性索引,當新的證照安裝時,我發現index會隨著增加。
  • perms 包含開發者已經在AndroidManifest.xml中設定好的許可權。

2. packages.list: 這是一個簡單的文字檔案,包含了包名、使用者id、flag和資料目錄,我找不到更加完美的描述了,但是我設想它可提供更快速的已安裝包的查詢,因為這個檔案一直只儲存重要的資訊。

3.packages-stoped.xml:這個檔案包含了已經是停止狀態的包的列表,停止狀態的應用是不能接收任何的廣播的。參考這個連結來了解更多關於停止狀態應用的資訊。http://yuki312.blogspot.in/2012/03/androidbroadcaststop.html

5、去哪裡可以找到Package Manager和Package Installer的原始碼?

Package Manger
frameworks/base/services/java/com/android/server/pm/Settings.java
frameworks/base/services/java/com/android/server/pm/PackageManagerService.java
frameworks/base/services/java/com/android/server/pm/IPackageManager.aidl
frameworks/base/services/java/com/android/server/pm/PackageSignatures.java
frameworks/base/services/java/com/android/server/pm/PreferredActivity.java
frameworks/services/java/com/android/server/PreferredComponent.java
frameworks/core/java/android/content/IntentFilter.java
frameworks/base/core/java/android/content/pm/PackageParser.java
frameworks/base/services/java/com/android/server/pm/Installer.java
frameworks/base/core/java/com/android/internal/app/IMediaContainerService.aidl
frameworks/base/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java

Package Installer
packages/apps/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
packages/apps/PackageInstaller/src/com/android/packageinstaller/PackageUtil.java
packages/apps/PackageInstaller/src/com/android/packageinstaller/InstallAppProgress.java

相關文章