Wert der Ressourcen einer App während der Laufzeit ändern

Ein Laufzeitressourcen-Overlay (RRO) ist ein Paket, das die Ressourcenwerte ändert. eines Zielpakets zur Laufzeit. Beispiel: eine auf dem System installierte App Das Verhalten eines Images kann sich auf Basis des Werts einer Ressource ändern. Anstelle von der Ressourcenwert zum Zeitpunkt der Build-Erstellung hartcodiert wird, Partition kann die Werte der App-Ressourcen zur Laufzeit ändern.

RROs können aktiviert oder deaktiviert werden. Sie können den Parameter Aktivierung/Deaktivierung des Status, um die Fähigkeit eines RRO zum Ändern von Ressourcenwerten zu aktivieren bzw. zu deaktivieren. RROs sind standardmäßig deaktiviert (statische RROs werden jedoch durch Standard).

Ressourcen einblenden

Bei Overlays werden im Overlay-Paket definierte Ressourcen Ressourcen zugeordnet. im Zielpaket definiert. Wenn eine App versucht, den Wert eines Ressource im Zielpaket, der Wert der Overlay-Ressource das Ziel der Ressource zurückgegeben wird.

Manifest einrichten

Ein Paket gilt als RRO-Paket, wenn es ein <overlay>-Tag als dem <manifest>-Tag untergeordnet ist.

  • Der Wert des erforderlichen android:targetPackage-Attributs gibt den Namen an. Pakets, das mit dem RRO überlagert werden soll.

  • Der Wert des optionalen android:targetName-Attributs gibt den Namen der Die einblendbare Teilmenge der Ressourcen des Zielpakets, das mit der RRO-Funktion verwendet werden soll -Overlay. Wenn das Ziel keinen überblendbaren Satz von Ressourcen definiert, wird dies sollte nicht vorhanden sein.

Der folgende Code zeigt ein Beispiel-Overlay-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>

Overlays können keinen Code überlagern, daher können sie keine DEX-Dateien enthalten. Darüber hinaus enthält der Attribut android:hasCode von <application> im Manifest muss auf false festgelegt.

Ressourcenzuordnung definieren

Unter Android 11 oder höher wird der empfohlene Mechanismus Definieren der Overlay-Ressourcenkarte besteht darin, eine Datei im res/xml zu erstellen. des Overlay-Pakets enthält, listen Sie die Zielressourcen auf, und ihre Ersatzwerte. Legen Sie dann den Wert des android:resourcesMap-Attribut des Manifest-Tags <overlay> mit einer Referenz. zur Ressourcenzuordnungsdatei hinzu.

Der folgende Code zeigt eine res/xml/overlays.xml-Beispieldatei.

<?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>

Der folgende Code zeigt ein Beispiel für ein Overlay-Manifest.

<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>

Paket erstellen

Android 11 oder höher unterstützt eine Soong-Build-Regel für Overlays, die verhindern, dass Android Asset Packaging Tool 2 (AAPT2) Konfigurationen von Ressourcen mit demselben Wert deduplizieren (--no-resource-deduping) und vom Entfernen von Ressourcen ohne Standardeinstellung Konfigurationen (--no-resource-removal) Der folgende Code zeigt ein Beispiel Android.bp-Datei.

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

Ressourcen auflösen

Wenn für eine Ziel- oder Overlay-Ressource mehrere Konfigurationen die abgefragte Ressource ist, gibt die Ressourcenlaufzeit den Wert der Konfiguration, die am besten zur Konfiguration der Gerätekonfiguration passt. Führen Sie die Parameter Gruppe der Overlay-Ressourcenkonfigurationen in die Gruppe der Zielressource und folgen Sie dann dem regulären Ablauf der Ressourcenauflösung (für Weitere Informationen finden Sie unter So findet Android die beste Übereinstimmung Ressource).

Wenn beispielsweise ein Overlay einen Wert für die drawable-en-Konfiguration definiert, und das Ziel einen Wert für drawable-en-port, drawable-en-port hat eine bessere Übereinstimmung, sodass der Wert der Zielkonfiguration drawable-en-port zur Laufzeit ausgewählt wird. Um alle drawable-en-Konfigurationen zu überlagern, muss für jede durch das Ziel definierte drawable-en-Konfiguration einen Wert definieren.

Overlays können auf ihre eigenen Ressourcen verweisen, mit unterschiedlichem Verhalten zwischen Android-Releases

  • Ab Android 11 hat jedes Overlay ein eigenes reservierten Ressourcen-ID-Bereich, der sich nicht mit dem Zielressourcen-ID-Bereich überschneidet, andere Overlay-Ressourcen-ID-Bereiche, sodass Overlays, die auf ihre eigenen Ressourcen verweisen, wie erwartet funktioniert.

  • In Android 10 oder niedriger nutzen Overlays und Zielpakete dieselbe Ressource ID-Bereich, der zu Konflikten und unerwartetem Verhalten führen kann, , um mit der Syntax @type/name auf ihre eigenen Ressourcen zu verweisen.

Overlays aktivieren/deaktivieren

Verwenden Sie die OverlayManager API, um änderbare Overlays zu aktivieren und zu deaktivieren (Abruf- API-Schnittstelle mithilfe von Context#getSystemService(Context.OVERLAY_SERVICE)) aufrufen. Eine Overlay kann nur von dem Paket aktiviert werden, auf das es ausgerichtet ist, oder von einem Paket mit der Berechtigung android.permission.CHANGE_OVERLAY_PACKAGES. Wenn ein Overlay aktiviert oder deaktiviert, werden Konfigurationsänderungsereignisse an das Zielpaket weitergegeben. und Zielaktivitäten neu starten.

Überspringbare Ressourcen einschränken

In Android 10 oder höher stellt das XML-Tag <overlayable> eine Reihe von Ressourcen bereit die RROs überlagern dürfen. Im folgenden Beispiel res/values/overlayable.xml-Datei, string/foo und integer/bar sind Ressourcen Sie werden für das Design des Geräts verwendet. um diese Ressourcen zu überlagern, muss explizit namentlich auf die Sammlung von überspringbaren Ressourcen ausgerichtet sein.

<!-- 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>

Ein APK kann mehrere <overlayable>-Tags definieren, aber jedes Tag muss eine eindeutige Namen im Paket angeben. Beispiel:

  • Es ist zulässig, dass zwei verschiedene Pakete <overlayable name="foo"> definieren.

  • Ein einzelnes APK darf nicht zwei <overlayable name="foo">-Blöcke enthalten.

Der folgende Code zeigt ein Beispiel für ein Overlay im AndroidManifest.xml -Datei.

<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>

Wenn in einer App ein <overlayable>-Tag definiert ist, werden folgende Overlays angezeigt, die auf diese App ausgerichtet sind:

  • targetName muss angegeben werden.

  • Kann nur die im <overlayable>-Tag aufgeführten Ressourcen überlagern.

  • Die Ausrichtung kann nur auf einen <overlayable>-Namen erfolgen.

Sie können kein Overlay aktivieren, das auf ein Paket ausgerichtet ist, das Ressourcen, verwendet jedoch nicht android:targetName für ein bestimmtes Ziel <overlayable>-Tag.

Richtlinien einschränken

Mit dem Tag <policy> können Sie Einschränkungen für überspringbare Ressourcen erzwingen. Die Das Attribut type gibt an, welche Richtlinien ein Overlay erfüllen muss, um es zu überschreiben die enthaltenen Ressourcen. Folgende Typen werden unterstützt.

  • public Jedes Overlay kann die Ressource überschreiben.
  • system Jedes Overlay auf der Systempartition kann die Ressourcen überschreiben.
  • vendor Jedes Overlay auf der Anbieterpartition kann die Ressourcen überschreiben.
  • product Jedes Overlay in der Produktaufteilung kann die Ressourcen überschreiben.
  • oem Jedes Overlay auf der OEM-Partition kann die Ressourcen überschreiben.
  • odm Jedes Overlay auf der OMD-Partition kann die Ressourcen überschreiben.
  • signature Jedes Overlay, das mit derselben Signatur wie das Ziel-APK signiert ist, die Ressourcen überschreiben.
  • actor Jedes Overlay, das mit derselben Signatur wie das Akteur-APK signiert ist, kann die Ressourcen überschreiben. Der Akteur wird im Tag named-actor im System deklariert. config.
  • config_signature Jedes Overlay, das mit derselben Signatur wie das Das APK overlay-config kann die Ressourcen überschreiben. Die Overlay-Konfiguration ist im Tag overlay-config-signature in der Systemkonfiguration deklariert.

Der folgende Code zeigt ein Beispiel für ein <policy>-Tag im res/values/overlayable.xml-Datei.

<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>

Wenn Sie mehrere Richtlinien angeben möchten, verwenden Sie vertikale Balken (|) als Trennzeichen. Wenn mehrere Richtlinien angegeben sind, muss ein Overlay nur eine Richtlinie erfüllen. Richtlinie, um die im Tag <policy> aufgeführten Ressourcen zu überschreiben.

Overlays konfigurieren

Android unterstützt verschiedene Mechanismen zum Konfigurieren der Veränderlichkeit, Status und Priorität von Overlays je nach Android-Release-Version.

  • Auf Geräten mit Android 11 oder höher kann ein OverlayConfig-Datei (config.xml) anstelle von Manifest-Attributen. Bei Verwendung eines Overlay-Datei ist die empfohlene Methode für Overlays.

  • Alle Geräte können Manifestattribute verwenden (android:isStatic und android:priority) zum Konfigurieren statischer RROs.

OverlayConfig verwenden

Ab Android 11 können Sie OverlayConfig für folgende Aktionen verwenden: Konfigurieren Sie die Veränderlichkeit, den Standardstatus und die Priorität von Overlays. Zum Konfigurieren eines Overlays ist, erstellen oder ändern Sie die Datei unter partition/overlay/config/config.xml, wobei partition die Partition des das zu konfigurieren ist. Zur Konfiguration muss sich ein Overlay im Das Verzeichnis overlay/ der Partition, in der das Overlay konfiguriert ist. Die Der folgende Code zeigt ein product/overlay/config/config.xml-Beispiel.

<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>"

Das <overlay>-Tag erfordert ein package-Attribut, das angibt, welches Overlay Paket wird konfiguriert. Mit dem optionalen Attribut enabled wird gesteuert, das Overlay ist standardmäßig aktiviert (Standardeinstellung ist false). Das optionale Feld Das Attribut mutable legt fest, ob das Overlay veränderbar ist und Der aktivierte Status wurde zur Laufzeit programmatisch geändert (Standardeinstellung ist true). Overlays, die nicht in einer Konfigurationsdatei aufgeführt sind, können durch Standardeinstellung.

Rangfolge der Overlays

Wenn mehrere Overlays dieselben Ressourcen überschreiben, ist die Reihenfolge der Overlays wichtig. Ein Overlay hat eine höhere Priorität als Overlays mit Konfigurationen seiner eigenen Konfiguration vorangestellt ist. Die Rangfolge von Overlays in verschiedenen (von der niedrigsten bis zur größten Priorität) wie folgt:

  • system
  • vendor
  • odm
  • oem
  • product
  • system_ext

Dateien zusammenführen

Mit <merge>-Tags können andere Konfigurationsdateien angegebene Position in der Konfigurationsdatei ein. Das Attribut path des Tags stellt den Pfad der zusammenzuführenden Datei relativ zum Verzeichnis dar, das Overlay-Konfigurationsdateien.

Manifestattribute/statische RROs verwenden

In Android 10 oder niedriger werden die Unveränderlichkeit und Rangfolge von Overlays mit die folgenden Manifest-Attribute.

  • android:isStatic Wenn der Wert dieses booleschen Attributs auf true festgelegt ist, Das Overlay ist standardmäßig aktiviert und unveränderlich. Dadurch wird verhindert, dass das Overlay deaktiviert werden kann.

  • android:priority Der Wert dieses numerischen Attributs, der nur statische Overlays) legt die Priorität des Overlays fest, wenn mehrere statische Overlays Overlays zielen auf denselben Ressourcenwert ab. Eine höhere Zahl bedeutet eine höhere Vorrang.

Der folgende Code zeigt ein AndroidManifest.xml-Beispiel.

<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>

Änderungen bei Android 11

Ist unter Android 11 oder höher eine Konfigurationsdatei befinden sich in partition/overlay/config/config.xml, werden Overlays mit diese Datei und android:isStatic und android:priority haben keine Auswirkungen auf Overlays, die sich in der Partition befinden. Overlay-Konfigurationsdatei in einer beliebigen -Partition erzwingt die Overlay-Partitionspriorität.

Außerdem ist ab Android 11 nicht mehr möglich, zur Verwendung statischer Overlays, um die Werte von Ressourcen zu beeinflussen, die während des Pakets gelesen werden Installation. Für den häufigen Anwendungsfall, bei dem statische Overlays verwendet werden, um zur Konfiguration des Aktivierungsstatus der Komponente verwenden, verwenden Sie <component-override> SystemConfig-Tag (neu in Android) 11).

Overlays zur Fehlerbehebung

Verwenden Sie das folgende Overlay, um Overlays manuell zu aktivieren, zu deaktivieren und abzubilden. Manager-Shell-Befehl.

adb shell cmd overlay

OverlayManagerService verwendet idmap2, um Ressourcen-IDs im Ziel zuzuordnen zu den Ressourcen-IDs im Overlay-Paket. Die generierten ID-Zuordnungen sind gespeichert in /data/resource-cache/. Falls das Overlay nicht richtig funktioniert, suchen Sie nach die entsprechende idmap-Datei für Ihr Overlay in /data/resource-cache/, dann führen Sie den folgenden Befehl aus.

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

Dieser Befehl gibt die Zuordnung der Ressourcen aus, wie unten gezeigt.

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