深度探究apk安裝過程

ReubenBattl 7年前發布 | 14K 次閱讀 安卓開發 Android開發 移動開發

一.先驗知識

0.PcakageaManagerService版本變化

1.概述

2.PackageManagerService服務啟動流程

3. PackageManagerService入口

二.四種安裝方式

1.系統應用安裝

2.網絡下載應用安裝

3. ADB工具安裝

4.第三方應用安裝

三.總結

概述

1.1概述

眾所周知, Android 應用最終是打包成.apk格式(其實就是一個壓縮包),然后安裝至手機并運行的。APK即Android Package的縮寫。

Android系統在啟動的過程中,會啟動一個應用程序管理服務PackageManagerService,這個服務負責掃描系統中特定的目錄,找到里面的應用程序文件,即以Apk為后綴的文件,然后對這些文件進解析,得到應用程序的相關信息,完成應用程序的安裝過程。

應用程序管理服務PackageManagerService安裝應用程序的過程,其實就是解析析應用程序配置文件AndroidManifest.xml的過程,并從里面得到得到應用程序的相關信息,例如得到應用程序的組件Activity、Service、Broadcast Receiver和Content Provider等信息,有了這些信息后,通過ActivityManagerService這個服務,我們就可以在系統中正常地使用這些應用程序了。

Android應用APK安裝的方式

一般而言,Android應用安裝有如下四種方式:

系統應用安裝:開機時加載系統的APK和應用,沒有安裝界面;

網絡下載應用安裝:通過各種market應用完成,沒有安裝界面;

ADB工具安裝:即通過Android的SDK開發tools里面的adb.exe程序安裝,沒有安裝界面;

第三方應用安裝:通過SD卡里的APK文件安裝(比如雙擊APK文件觸發),有安裝界面,系統默認已經安裝了一個安裝卸載應用的程序,即由packageinstaller.apk應用處理安裝及卸載過程的界面。

應用安裝涉及到的目錄

/system/app :系統自帶的應用程序,獲得adb root權限才能刪除

/data/app :用戶程序安裝的目錄。安裝時把apk文件復制到此目錄

/data/data :存放應用程序的數據

/data/dalvik-cache:將apk中的dex文件安裝到dalvik-cache目錄下(dex文件是dalvik虛擬機的可執行文件,當然,ART–Android Runtime的可執行文件格式為oat,啟用ART時,系統會執行dex文件轉換至oat文件)

/data/system :該目錄下的packages.xml文件,類似于Windows的注冊表,這個文件是在解析apk時由writeLP()創建的,里面記錄了系統的permissions,以及每個apk的name,codePath,flags,ts,version,uesrid等信息,這些信息主要通apk的AndroidManifest.xml解析獲取,解析完apk后將更新信息寫入這個文件并保存到flash,下次開機直接從里面讀取相關信息添加到內存相關列表中。當有apk升級,安裝或刪除時會更新這個文件。

/data/system/packages.xml中內容詳解(這里列舉的標簽內容不一定完整,只是列舉核心內容,packages.xml的完整定義詳見官方文檔):

安裝概述

(1) 拷貝apk文件到指定目錄

在Android系統中,apk安裝文件是會被保存起來的,默認情況下,用戶安裝的apk首先會被拷貝到 /data/app 目錄下。

/data/app目錄是用戶有權限訪問的目錄,在安裝apk的時候會自動選擇該目錄存放用戶安裝的文件,而系統出廠的apk文件則被放到了 /system 分區下,包括 /system/app,/system/vendor/app,以及 /system/priv-app 等等,該分區只有Root權限的用戶才能訪問,這也就是為什么在沒有Root手機之前,我們無法刪除系統出廠的app的原因了。

(2) 解壓apk,拷貝文件,創建應用的數據目錄

為了加快app的啟動速度,apk在安裝的時候,會首先將app的可執行文件(dex)拷貝到 /data/dalvik-cache 目錄,緩存起來。

然后,在/data/data/目錄下創建應用程序的數據目錄(以應用的包名命名),存放應用的相關數據,如 數據庫 、xml文件、cache、二進制的so動態庫等等。

(3) 解析apk的AndroidManifinest.xml文件

Android系統中,也有一個類似注冊表的東西,用來記錄當前所有安裝的應用的基本信息,每次系統安裝或者卸載了任何apk文件,都會更新這個文件。這個文件位于如下目錄:

/data/system/packages.xml

系統在安裝apk的過程中,會解析apk的AndroidManifinest.xml文件,提取出這個apk的重要信息寫入到packages.xml文件中,這些信息包括:權限、應用包名、APK的安裝位置、版本、userID等等。

由此,我們就知道了為啥一些應用市場和軟件管理類的app能夠很清楚地知道當前手機所安裝的所有的app,以及這些app的詳細信息了。

另外一件事就是 Linux 的用戶Id和用戶組Id,以便他可以獲得合適的運行權限。

以上這些都是由PackageServiceManager完成的,下面我們會重點介紹PackageServiceManager。

(4) 顯示快捷方式

這些應用程序只是相當于在PackageManagerService服務注冊好了,如果我們想要在Android桌面上看到這些應用程序,還需要有一個Home應用程序,負責從PackageManagerService服務中把這些安裝好的應用程序取出來,并以友好的方式在桌面上展現出來,例如以快捷圖標的形式。在Android系統中,負責把系統中已經安裝的應用程序在桌面中展現出來的Home應用程序就是Launcher了

1.2 PackageManagerService啟動過程

1.3 PackageManagerService入口

2.1系統應用安裝方式

2.1系統應用安裝方式

第一步:1.PackageManagerService.main()初始化注冊

將PackageManagerService服務初始化并注冊到ServiceManager里面進行管理。

第二步:2.建立java層的installer與c層的installd的socket聯接

建立 Java 層的installer與c層的installd的socket聯接,使得在上層的install,remove,dexopt等功能最終由installd在底層實現;

第三步:3.建立PackageHandler消息循環

建立PackageHandler消息循環,用于處理外部的apk安裝請求消息,如adb install,packageinstaller安裝apk時會發送消息;

典型的比如INIT_COPY和MCS_BOUND等,在通過網絡下載時候會調用。

第四步:4. 成員變量readLp()恢復上一次的安裝信息

由于Android每次啟動的時候都需要安裝一次信息,但是有些信息是保持不變的,例如Linux用戶組Id,PackageManagerService 每次安裝程序之后,都會把這些程序的信息保存下來,以便下次使用, 恢復上一次程序的安裝信息是通過PackageManagerService 的成員變量mSetting的readLP()來實現的,恢復信息之后就開始掃描和安裝app了。

檢查/data/system/packages.xml是否存在,這個文件是在解析apk時由writeLP()創建的,里面記錄了系統的permissions,以及每個apk的name,codePath,flags,ts,version,uesrid等信息,這些信息主要通過apk的AndroidManifest.xml解析獲取,解析完apk后將更新信息寫入這個文件并保存到flash,下次開機直接從里面讀取相關信息添加到內存相關列表中。當有apk升級,安裝或刪除時會更新這個文件。

第五步:5.jar的detopt優化

檢查BootClassPath,mSharedLibraries及/system/framework下的jar是否需要dexopt,需要的則通過dexopt進行優化;

第六步:6.scanDirLI函數掃描特定目錄的apk文件解析

啟動AppDirObserver線程監測/system/framework,/system/app,/data/app,/data/app-private目錄的事件,主要監聽add和remove事件。對于目錄監聽底層通過inotify機制實現,inotify 是一種文件系統的變化通知機制,如文件增加、刪除等事件可以立刻讓用戶態得知,它為用戶態監視文件系統的變化提供了強大的支持。當有add event時調用scanPackageLI(File , int , int)處理;當有remove event時調用removePackageLI()處理;

調用installer.install()進行安裝工作,檢查apk里的dex文件是否需要再優化,如果需要優化則通過輔助工具dexopt進行優化處理;將解析出的componet添加到pkg的對應列表里;對apk進行簽名和證書校驗,進行完整性驗證。

第七步:7.updatePermmisonLp函數分配權限

這個函數為申請了特定資源訪問權限的app,分配相應的用戶組ID.

第八步:8.writeLP()函數保存安裝信息

mSetting的writeLP()將所獲得應用程序的安裝信息,保存在一個本地的配置文件中。以便下次安裝的時候,將應用的信息回復過來。

2.1系統應用安裝方式

2.2網絡下載應用安裝

2.3 ADB工具安裝

2.4第三方應用安裝

![這里寫圖片描述]( http://img.blog.csdn.net/20170310214918051?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHBqaXNodQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/

三.總結

1.安裝和卸載都是通過PackageManager,實質上是實現了PackageManager的遠程服務PackageManagerService來完成具體的操作,所有細節和邏輯均可以在PackageManagerService中跟蹤查看;

2.所有安裝方式殊途同歸,最終就回到PackageManagerService中,然后調用底層本地代碼的installd來完成。

再看apk 的安裝過程。

回個我們再看真個apk的安裝過程,主要分為如下幾部

拷貝apk文件到指定目錄

解壓apk,拷貝文件,創建應用的數據目錄

解析apk的AndroidManifinest.xml文件

向Launcher應用申請添加創建快捷方式

參考:

《Android源代碼情景分析》

《Android內核分析》

http://blog.csdn.net/luoshengyang/article/details/6766010

http://blog.csdn.net/hdhd588/article/details/6739281

http://ticktick.blog.51cto.com/823160/1669525

http://www.jianshu.com/p/953475cea991

http://cstsinghua.github.io/2016/06/13/Android%E5%AE%89%E8%A3%85APK%E8%AF%A6%E8%A7%A3/

http://junshengluo.com/2016/11/30/android-5-%E6%8E%A2%E7%A9%B6%20Android%20%20apk%20%E5%AE%89%E8%A3%85%E8%BF%87%E7%A8%8B/

 

來自:http://www.androidchina.net/6667.html

 

 本文由用戶 ReubenBattl 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!