在執行階段變更應用程式的值('s)

執行階段資源疊加層 (RRO) 是會變更資源值的套件 執行 YAML 檔案例如安裝在系統上的應用程式 映像檔的行為可能會根據資源的值變更行為與其 在建構期間以硬式編碼的方式寫入資源值,並將 RRO 安裝在 分區可以在執行階段變更應用程式的資源值。

RRO 可啟用或停用。您可以用程式輔助方式設定 啟用/停用狀態,切換 RRO 變更資源值的功能。RRO 靜態 RRO 預設為停用狀態 )。

重疊資源

疊加層的運作方式是將疊加層套件中定義的資源對應至資源 指定的 Deployment 版本當應用程式嘗試解析 是目標套件的資源,這是目標疊加層資源的值 則會改為傳回已對應至 的 資源。

設定資訊清單

如果套件包含 <overlay> 標記做為 <manifest> 標記的子項。

  • 必要 android:targetPackage 屬性的值會指定名稱 RRO 預計要疊加的套件。

  • 選擇性 android:targetName 屬性的值可指定 目標套件的可重疊部分資源子集 重疊。如果目標未定義一組可重疊的資源集, 屬性不應出現。

以下程式碼是疊加層 AndroidManifest.xml 的範例。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.overlay">
    <application android:hasCode="false" />
    <overlay android:targetPackage="com.example.target"
                   android:targetName="OverlayableResources"/>
</manifest>

疊加層無法疊加程式碼,因此無法含有 DEX 檔案。此外, <applicationandroid:hasCode 屬性資訊清單中的標記必須 已設為 false

定義資源對應

在 Android 11 以上版本中, 定義疊加層資源對應是在 res/xml 中建立檔案 疊加層套件的 目錄,列舉應在 然後設定相應的替換值 <overlay> 資訊清單標記的 android:resourcesMap 屬性 對應至資源對應檔案

以下程式碼為 res/xml/overlays.xml 檔案範例。

<?xml version="1.0" encoding="utf-8"?>
<overlay xmlns:android="http://schemas.android.com/apk/res/android" >
    <!-- Overlays string/config1 and string/config2 with the same resource. -->
    <item target="string/config1" value="@string/overlay1" />
    <item target="string/config2" value="@string/overlay1" />

    <!-- Overlays string/config3 with the string "yes". -->
    <item target="string/config3" value="@android:string/yes" />

    <!-- Overlays string/config4 with the string "Hardcoded string". -->
    <item target="string/config4" value="Hardcoded string" />

    <!-- Overlays integer/config5 with the integer "42". -->
    <item target="integer/config5" value="42" />
</overlay>

以下程式碼為疊加層資訊清單範例。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.overlay">
    <application android:hasCode="false" />
    <overlay android:targetPackage="com.example.target"
                   android:targetName="OverlayableResources"
                   android:resourcesMap="@xml/overlays"/>
</manifest>

建構套件

Android 11 以上版本支援使用 Soong 建構規則, 避免 Android 資產封裝工具 2 (AAPT2) 嘗試的重疊元素 刪除擁有相同值的資源設定 (--no-resource-deduping) 以及移除沒有預設值的資源 設定 (--no-resource-removal)。以下程式碼範例說明 Android.bp 檔案。

runtime_resource_overlay {
    name: "ExampleOverlay",
    sdk_version: "current",
}

解析資源

如果目標資源或疊加層資源已定義多個 所查詢的資源,則資源執行階段會傳回 找出最符合裝置設定的設定。 如要判斷哪個設定最適合,請合併 一組重疊資源設定至目標資源組合 然後按照一般資源解析流程執行 詳情請參閱 Android 如何尋找 資源)。

例如,如果疊加層為 drawable-en 設定定義值 而目標定義了 drawable-en-portdrawable-en-port 的值 比對結果較佳,因此目標設定值 drawable-en-port 的值更好 都是在執行階段選擇的疊加所有 drawable-en 設定 必須為目標定義的每個 drawable-en 設定定義一個值。

疊加層可以參照其本身的資源,但兩者的行為模式 Android 版本。

  • 在 Android 11 以上版本中,每個疊加層都有專屬 與目標資源 ID 空間沒有重疊的預留資源 ID 空間,或是 其他疊加層資源 ID 空間,因此疊加層會參照本身的資源 正常運作,

  • 在 Android 10 以下版本中,重疊和目標套件共用相同的資源 ID 空間,在嘗試時可能產生衝突和非預期的行為 使用 @type/name 語法參照自己的資源。

啟用/停用重疊圖層

使用 OverlayManager API 啟用及停用可變動疊加層 (擷取) 透過 Context#getSystemService(Context.OVERLAY_SERVICE) 取得 API 介面)。一個 只能藉由其指定的套件或具有 android.permission.CHANGE_OVERLAY_PACKAGES權限。疊加層處於 設定變更事件會套用至目標套件 並重新啟動目標活動

限制可重疊的資源

在 Android 10 以上版本中,<overlayable> XML 標記會公開一組資源 RRO 允許疊加在一起在以下範例中 res/values/overlayable.xml 檔案、string/foointeger/bar 是資源 用於設定裝置外觀主題;疊加這些資源 必須按名稱明確指定可重疊資源的集合。

<!-- The collection of resources for theming the appearance of the device -->
<overlayable name="ThemeResources">
       <policy type="public">
               <item type="string" name="foo/" />
               <item type="integer" name="bar/" />
       </policy>
       ...
</overlayable>

APK 可以定義多個 <overlayable> 標記,但每個標記都必須不重複 套件名稱。例如:

  • 兩個不同的套件都能定義 <overlayable name="foo">

  • 單一 APK 不得含有兩個 <overlayable name="foo"> 區塊。

以下程式碼為 AndroidManifest.xml 中的疊加層範例 檔案。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="com.my.theme.overlay">
       <application android:hasCode="false" />
       <!-- This overlay will override the ThemeResources resources -->
       <overlay android:targetPackage="android" android:targetName="ThemeResources">
</manifest>

應用程式定義 <overlayable> 標記時,會指定該應用程式的重疊圖層:

  • 必須指定 targetName

  • 只能重疊 <overlayable> 標記中列出的資源。

  • 只能指定一個「<overlayable>」名稱。

您無法啟用指定重疊程式的套件來指定可重疊顯示的套件 但並非使用 android:targetName 指定 <overlayable> 標記。

限制政策

使用 <policy> 標記即可對可重疊的資源強制執行限制。 type 屬性會指定疊加層必須符合哪些政策才能覆寫 請參閱所含資源支援的類型包括:

  • public。任何重疊元素都能覆寫資源。
  • system。系統分區上的任何重疊元素都可以覆寫資源。
  • vendor。廠商分區上的任何重疊元素都可以覆寫資源。
  • product。產品分區上的任何重疊元素都可以覆寫資源。
  • oem。oem 分區上的任何重疊元素都可以覆寫資源。
  • odm。奇數分區上的任何重疊元素都可以覆寫資源。
  • signature。任何與目標 APK 使用相同簽章簽署的重疊元素,都可以 會覆寫資源
  • actor。任何與 actor APK 使用相同簽章簽署的重疊圖層, 覆寫資源演員在系統中的 named-actor 標記中宣告 設定檔。
  • config_signature。任何使用與 overlay-config APK 可以覆寫資源。疊加層設定為 您在系統設定中的 overlay-config-signature 代碼中宣告:

下方程式碼為<policy> res/values/overlayable.xml 檔案。

<overlayable name="ThemeResources">
   <policy type="vendor" >
       <item type="string" name="foo" />
   </policy>
   <policy type="product|signature"  >
       <item type="string" name="bar" />
       <item type="string" name="baz" />
   </policy>
</overlayable>

如要指定多項政策,請使用垂直線 (|) 做為分隔字元。 如果指定多項政策,重疊元素就只需要滿足一項政策 政策,覆寫 <policy> 標記中列出的資源。

設定疊加層

Android 支援不同的可變動性設定機制 (預設值 並根據 Android 發布版本 決定疊加層的優先順序

  • 搭載 Android 11 以上版本的裝置可以使用 OverlayConfig 檔案 (config.xml) 而非資訊清單屬性。使用 建議您使用疊加層檔案這個方法。

  • 所有裝置都能使用資訊清單屬性 (android:isStaticandroid:priority) 來設定靜態 RRO。

,瞭解如何調查及移除這項存取權。

使用 OverlayConfig

在 Android 11 以上版本中,您可以使用 OverlayConfig 執行下列操作: 設定疊加層的可變動性、預設狀態和優先順序。如要設定 建立或修改位於 partition/overlay/config/config.xml,其中 partition 是 要設定的一組層如要設定,疊加層必須位在 設定疊加層的分區 overlay/ 目錄。 下列程式碼顯示 product/overlay/config/config.xml 範例。

<config>
    <merge path="OEM-common-rros-config.xml" />
    <overlay package="com.oem.overlay.device" mutable="false" enabled="true" />
    <overlay package="com.oem.green.theme" enabled="true" />
</config>"

<overlay> 標記需要 package 屬性,用於指定疊加層 正在設定套件。選用的 enabled 屬性可控制 或不預設啟用疊加層 (預設為 false)。您可視需要 mutable 屬性控制是否可變動疊加層,且能 在執行階段,以程式輔助方式變更其已啟用狀態 (預設為 true)。 未列在設定檔中的疊加層可變動, 預設值。

疊加層優先順序

當多個疊加層覆寫相同的資源時,疊加層的順序會 非常重要疊加層的優先順序高於設定中的疊加層優先順序 所屬的資料夾不同區域中的疊加層優先順序 分區 (從最低優先順序到最高優先順序) 如下所述。

  • system
  • vendor
  • odm
  • oem
  • product
  • system_ext
,瞭解如何調查及移除這項存取權。

合併檔案

使用 <merge> 標記可允許其他設定檔 所指定的位置放入設定檔標記的 path 屬性 代表要合併的檔案路徑,相對於包含 目錄的 目錄 疊加設定檔

使用資訊清單屬性/靜態 RRO

在 Android 10 以下版本中,系統會透過 下列資訊清單屬性

  • android:isStatic。當這個布林值屬性的值設為 true 時, 疊加層預設為啟用,且不可變動,否則會阻止 並停用

  • android:priority。這個數值屬性的值 (只會影響 靜態疊加層) 會在多個靜態元素發生時,設定疊加層的優先順序 疊加層指定相同的資源值數字越大表示 優先順序。

以下程式碼為 AndroidManifest.xml 範例。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.overlay">
    <application android:hasCode="false" />
    <overlay android:targetPackage="com.example.target"
                   android:isStatic="true"
                   android:priority="5"/>
</manifest>

Android 11 的異動

在 Android 11 以上版本中,如果設定檔 位於 partition/overlay/config/config.xml,疊加層是使用 這個檔案和「android:isStatic」和「android:priority」並未對 位於分區內。在任意位置中定義疊加層設定檔 分區會強制執行重疊分區的優先順序。

此外,Android 11 以上版本移除了相關功能 使用靜態疊加層來影響在套件中讀取的資源值 安裝。我們常使用靜態疊加層來變更 設定元件啟用狀態的布林值,請使用 <component-override> SystemConfig 標記 (Android 新功能 11)。

偵錯疊加層

如要手動啟用、停用及傾印疊加層,請使用以下疊加層 管理員殼層指令

adb shell cmd overlay

OverlayManagerService 會使用 idmap2 對應目標中的資源 ID 封裝至疊加層套件中的資源 ID。系統產生的 ID 對應項目如下 儲存在「/data/resource-cache/」中。如果您的疊加層無法正常運作,請參閱 在 /data/resource-cache/ 中為疊加層對應的 idmap 檔案,那麼 執行下列指令。

adb shell idmap2 dump --idmap-path [file]

這個指令會顯示資源對應關係,如下所示。

[target res id] - > [overlay res id] [resource name]
0x01040151 -> 0x01050001 string/config_dozeComponent
0x01040152 -> 0x01050002 string/config_dozeDoubleTapSensorType
0x01040153 -> 0x01050003 string/config_dozeLongPressSensorType