Android 系統 overlay 機制重點小結

qiracle發表於2017-09-25

靜態 overlay 和動態 overlay

靜態 overlay:又稱為編譯時 overlay,編譯時資源就已經覆蓋了,一般用在有原始碼的apk中。
動態 overlay:又稱為執行時 overlay,當 apk 在手機中執行時才發生資源覆蓋,一般用在無原始碼的apk中。

overlay資源替換的前提和原則

前提:資源所在路徑必須與overlay下資源路徑完全相同。如要替換 Settings 這個應用的String.xml裡的資源,該資原始檔所在路徑為packages/apps/res/values/,則對應overlay的路徑必須為overlay/packages/apps/res/values/。

原則:overlay替換的是資源,不是檔案。舉個例子,應用中String.xml裡的內容如下:

<String name="a">aaa</String>
<String name="b">bbb</String>
<String name="c">ccc</String>複製程式碼

overlay中的String.xml裡的內容如下:

<String name="a">abc</String>複製程式碼

則最終,apk呼叫的資源如下:

<String name="a">abc</String>
<String name="b">bbb</String>
<String name="c">ccc</String>複製程式碼

而不是想象的如下:

<String name="a">abc</String>複製程式碼

注意,關於替換,查詢相關英文文件發現有如下描述

For color, bool, string, array, style/theme types, the resource values are identifed by their keys, so for these types, there is no need to put the resources in a file with the same name as in the original base package.

For layout, animation, picture drawables and raw types, the resources are indentifed by their file name, and overlay for these resources should keep the file name same as in the base packages.

翻譯成中文的大概意思就是:
1.對於color,bool,String,array,style等資源的值是有他們的鍵確定的,比如

<String name="a">abc</String>

該字串資源通過鍵 name = "a" 來唯一確定值 abc 。也就是說,overlay裡的這類資原始檔的檔名不需要與應用包裡的資原始檔的檔名保持一致。只需要,資原始檔裡的鍵保持一致就行了。

2.對於佈局檔案,動畫檔案,圖片資原始檔等,這些資原始檔是通過檔名來唯一確定,所以overlay裡的這類資原始檔需要與應用包裡的資原始檔的檔名保持一致。

多個overlay的優先順序判定

在mk檔案中通過定義PRODUCT_PACKAGE_OVERLAYS或DEVICE_PACKAGE_OVERLAYS變數,後面可以加上多個overlay目錄路徑,以此來實現多個overlay目錄。但是這些目錄是有優先順序順序的,PRODUCT_PACKAGE_OVERLAYS下的目錄優先順序高於DEVICE_PACKAGE_OVERLAYS下目錄的優先順序,寫在前面的目錄優先順序高於寫在後面目錄的優先順序,舉個例子:

PRODUCT_PACKAGE_OVERLAYS = overlay_A overlay_B
DEVICE_PACKAGE_OVERLAYS = overlay_C overlay_D複製程式碼

上述overlay目錄優先順序順序:overlay_A >overlay_B> overlay_C >overlay_D

overlay用於新增資源

預設情況下,overlay目錄的資原始檔內容只能覆蓋原有軟體包中的資源,而不能新增資源。不讓會造成編譯錯誤。如要允許增加資源,可以將資源放入標籤中,或者一種更加簡便的方法是給aapt命令增加--auto-add-overlay選項。

相關文章