?(十)PMS及App安裝過程
?PMS,全稱PackageManagerService,是用來獲取Apk包的信息的。
?在前面分析四大組件與AMS通信的時候,我們介紹過,AMS總是會使用PMS加載包的信息,將其封裝在LoadedApk這個類對象中,然后我們就可以從中取出在manifest聲明的四大組件信息了。
(一)
?在下載并安裝App的過程,會把Apk存放在data/app目錄下。
?Apk是一個zip壓縮包,在文件頭會記錄壓縮包的大小,所以后續在文件尾巴就算是追加一部小電影,也不會對解壓造成影響——木馬其實就是這個思路,在可執行文件exe尾巴上掛一個木馬病毒,執行exe的同時也會執行這個木馬,然后你就中招了。
?我們可以把木馬思想運用在Android多渠道打包上。在比較老的Android 4.4版本中,我們會在Apk尾巴上追加幾個字節,來標記Apk的渠道。Apk啟動的時候,從apk中的尾巴上讀取這個渠道值。
?后來Google也發現這個安全漏洞了,在新版本的系統中,就會在Apk安裝的時候,檢查Apk的實際大小,看這個值與Apk的頭部記錄的壓縮包大小,是否相等,不相等就會報錯說安裝失敗。
(二)
?我們繼續說App的安裝過程。Android系統使用PMS解析這個Apk中的manifest文件,包括:
- 四大組件的信息,比如說,前面講過的靜態Receiver。比如說默認啟動的Activity。
- 分配用戶Id和用戶組Id。用戶Id是唯一的,因為Android是一個Linux系統。用戶組Id指的是各種權限,每個權限都在一個用戶組中,比如讀寫SD卡,比如網絡訪問,分配了哪些用戶組Id,就擁有了哪些權限。
? 3)在Launcher生成一個icon,icon中保存著默認啟動的Activity的信息。
? 4)App安裝過程的最后,是把上面這些信息記錄在一個xml文件中,以備下次安裝時再次使用。
(三)
?其實,在Android手機系統每次啟動的時候,都會使用PMS,把Android系統中的所有Apk都安裝一遍,一共4個步驟,如下所示:
?其中的第3步、第4步,和單獨安裝一個App的步驟是一樣的。我們分析一下前兩步:
?第1步,因為結束安裝的時候,都會把安裝信息保存在xml文件中,所以Android系統再次啟動時,再次重新安裝所有的Apk,就可以直接讀取之前保存的xml文件了。
?第2步,從5個目錄中讀取并安裝所有的apk。
?最后,回答前面提及的一個問題,為什么App安裝時,不把它解壓呢?直接從解壓文件中讀取資源文件比如圖片是不是更快呢?其實并不是這樣的,這部分邏輯需要到底層C++的代碼去尋找,我沒有具體看過,只是道聽途說問過Lody,他是這么給我解釋的:
?每次從apk中讀取資源,并不是先解壓再找圖片資源,而是解析Apk中的Resource.arsc文件,這個文件中存儲著資源的所有信息,包括資源在Apk中的地址、大小等等,按圖索驥,從這個文件中快速找到相應的資源文件。這是一種很高效的算法。
?不解壓Apk的好處,自然是節省空間。