1. 程式人生 > >寫給Android App開發人員看的Android底層知識(8)

寫給Android App開發人員看的Android底層知識(8)

(十)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的好處,自然是節省空間。