天天看點

寫給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個步驟,如下所示:

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

其中的第3步、第4步,和單獨安裝一個App的步驟是一樣的。我們分析一下前兩步:

      第1步,因為結束安裝的時候,都會把安裝資訊儲存在xml檔案中,是以Android系統再次啟動時,再次重新安裝所有的Apk,就可以直接讀取之前儲存的xml檔案了。

      第2步,從5個目錄中讀取并安裝所有的apk。

      最後,回答前面提及的一個問題,為什麼App安裝時,不把它解壓呢?直接從解壓檔案中讀取資源檔案比如圖檔是不是更快呢?其實并不是這樣的,這部分邏輯需要到底層C++的代碼去尋找,我沒有具體看過,隻是道聽途說問過Lody,他是這麼給我解釋的:

      每次從apk中讀取資源,并不是先解壓再找圖檔資源,而是解析Apk中的Resource.arsc檔案,這個檔案中存儲着資源的所有資訊,包括資源在Apk中的位址、大小等等,按圖索骥,從這個檔案中快速找到相應的資源檔案。這是一種很高效的算法。

      不解壓Apk的好處,自然是節省空間。