Modifica il valore delle risorse di un'app in fase di runtime

Un overlay di risorse di runtime è un pacchetto che modifica i valori delle risorse di un pacchetto target in fase di runtime. Ad esempio, un'app installata sul sistema potrebbe cambiare il proprio comportamento in base al valore di una risorsa. Anziché hardcoded del valore della risorsa al momento della creazione, un RRO installato può modificare i valori delle risorse dell'app in fase di runtime.

Gli RRO possono essere attivati o disattivati. Puoi impostare in modo programmatico stato di abilitazione/disabilitazione per attivare/disattivare la capacità di un RRO di modificare i valori delle risorse. RRO sono disattivate per impostazione predefinita (tuttavia, gli RRO statici vengono attivati predefinita).

Risorse overlay

Gli overlay funzionano mappando le risorse definite nel pacchetto di overlay alle risorse definita nel pacchetto di destinazione. Quando un'app tenta di risolvere il valore di un risorsa nel pacchetto di destinazione, il valore della risorsa overlay a cui è mappata la risorsa.

Configurare il file manifest

Un pacchetto è considerato un pacchetto RRO se contiene un tag <overlay> come del tag <manifest>.

  • Il valore dell'attributo obbligatorio android:targetPackage specifica il nome del pacchetto che l'RRO intende sovrapporre.

  • Il valore dell'attributo facoltativo android:targetName specifica il nome di il sottoinsieme sovrapposto di risorse del pacchetto target che l'RRO intende in overlay. Se il target non definisce un insieme sovrapposto di risorse, non deve essere presente.

Il seguente codice mostra un overlay di esempio 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>

Gli overlay non possono sovrapporre codice, quindi non possono contenere file DEX. Inoltre, Attributo android:hasCode di <application> nel file manifest deve essere impostato su false.

Definisci la mappa delle risorse

In Android 11 o versioni successive, il meccanismo consigliato per la definizione della mappa delle risorse overlay consiste nel creare un file in res/xml directory del pacchetto overlay, elenca le risorse di destinazione che dovrebbero in overlay e sui relativi valori di sostituzione, quindi imposta il valore attributo android:resourcesMap del tag manifest <overlay> a un riferimento al file di mappatura delle risorse.

Il seguente codice mostra un file res/xml/overlays.xml di esempio.

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

Il seguente codice mostra un esempio di manifest 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>

Creazione del pacchetto

Android 11 o versioni successive supporta una regola di build Presto per di overlay che impediscono allo strumento Android Asset Packaging Tool 2 (AAPT2) di tentare deduplicare configurazioni di risorse con lo stesso valore (--no-resource-deduping) e alla rimozione di risorse senza valori predefiniti configurazioni (--no-resource-removal). Il seguente codice mostra un esempio Android.bp file.

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

Risoluzione delle risorse

Se una risorsa target o una risorsa overlay hanno più configurazioni definite per alla risorsa sottoposta a query, il runtime delle risorse restituisce il valore di configurazione che meglio corrisponde a quella della configurazione del dispositivo. Per determinare quale sia la configurazione migliore corrispondente, unisci le delle configurazioni delle risorse overlay nell'insieme delle risorse di destinazione e seguire il normale flusso di risoluzione delle risorse (ad consulta l'articolo In che modo Android trova risorsa).

Ad esempio, se un overlay definisce un valore per la configurazione drawable-en e il target definisce un valore per drawable-en-port, drawable-en-port ha una corrispondenza migliore, quindi il valore della configurazione target drawable-en-port viene scelto in fase di esecuzione. Per sovrapporre tutte le configurazioni di drawable-en, l'overlay deve definire un valore per ogni configurazione drawable-en definita dal target.

Gli overlay possono fare riferimento alle proprie risorse, con comportamenti diversi tra Release di Android.

  • In Android 11 o versioni successive, ogni overlay ha il proprio spazio di ID risorsa riservato che non si sovrappone allo spazio ID risorsa di destinazione altri spazi ID risorsa overlay, pertanto gli overlay che fanno riferimento alle proprie risorse funzionino come previsto.

  • In Android 10 o versioni precedenti, gli overlay e i pacchetti di destinazione condividono la stessa risorsa spazio ID, che può causare collisioni e comportamenti imprevisti durante i tentativi per fare riferimento alle proprie risorse utilizzando la sintassi @type/name.

Attivazione/disattivazione degli overlay

Utilizza l'API OverlayManager per attivare e disattivare gli overlay modificabili (recupero l'interfaccia API utilizzando Context#getSystemService(Context.OVERLAY_SERVICE)). Un l'overlay può essere attivato solo dal pacchetto scelto come target o da un pacchetto con Autorizzazione android.permission.CHANGE_OVERLAY_PACKAGES. Quando un overlay viene attivata o disattivata, gli eventi di modifica della configurazione si propagano al pacchetto di destinazione e le attività target.

Limita risorse sovrapponibili

In Android 10 o versioni successive, il tag XML <overlayable> espone un insieme di risorse che gli RRO possono sovrapporre. Nell'esempio seguente res/values/overlayable.xml file, string/foo e integer/bar sono risorse utilizzati per definire a tema l'aspetto del dispositivo; per sovrapporre queste risorse, deve scegliere esplicitamente come target la raccolta di risorse sovrapponibili per nome.

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

Un APK può definire più tag <overlayable>, ma ogni tag deve avere un all'interno del pacchetto. Ad esempio:

  • È possibile che due pacchetti diversi definiscano entrambi <overlayable name="foo">.

  • Non è possibile che un singolo APK abbia due blocchi <overlayable name="foo">.

Il seguente codice mostra un esempio di overlay in 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>

Quando un'app definisce un tag <overlayable>, il targeting dell'app viene sovrapposto:

  • Devi specificare targetName.

  • Può sovrapporsi solo alle risorse elencate all'interno del tag <overlayable>.

  • Puoi scegliere come target un solo nome <overlayable>.

Non puoi attivare un overlay che ha come target un pacchetto che espone overlay ma non utilizza android:targetName per scegliere come target uno specifico Tag <overlayable>.

Limita criteri

Utilizza il tag <policy> per applicare limitazioni alle risorse sovrapponibili. La L'attributo type specifica i criteri che devono essere soddisfatti da un overlay per poter essere sostituiti le risorse incluse. I tipi supportati sono quelli riportati di seguito.

  • public. Qualsiasi overlay può sostituire la risorsa.
  • system. Qualsiasi overlay sulla partizione di sistema può sostituire le risorse.
  • vendor. Qualsiasi overlay sulla partizione del fornitore può sostituire le risorse.
  • product. Qualsiasi overlay sulla partizione del prodotto può eseguire l'override delle risorse.
  • oem. Qualsiasi overlay sulla partizione dell'OEM può eseguire l'override delle risorse.
  • odm. Qualsiasi overlay sulla partizione odm può sostituire le risorse.
  • signature. Qualsiasi overlay firmato con la stessa firma dell'APK target può un override delle risorse.
  • actor. Qualsiasi overlay firmato con la stessa firma dell'APK attore può un override delle risorse. L'attore è dichiarato nel tag named-actor nel sistema .
  • config_signature. Qualsiasi overlay firmato con la stessa firma overlay-config può sostituire le risorse. La configurazione dell'overlay è dichiarata nel tag overlay-config-signature nella configurazione di sistema.

Il seguente codice mostra un tag <policy> di esempio nella res/values/overlayable.xml file.

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

Per specificare più criteri, utilizza le barre verticali (|) come separatori. Se vengono specificati più criteri, un overlay deve soddisfare solo uno per eseguire l'override delle risorse elencate all'interno del tag <policy>.

Configurare gli overlay

Android supporta diversi meccanismi per configurare la mutabilità, impostazione predefinita lo stato e la priorità degli overlay in base alla versione di Android.

  • I dispositivi con Android 11 o versioni successive possono utilizzare un OverlayConfig (config.xml) anziché gli attributi del file manifest. L'utilizzo di un di overlay è il metodo consigliato per gli overlay.

  • Tutti i dispositivi possono utilizzare gli attributi del file manifest (android:isStatic e android:priority) per configurare gli RRO statici.

di Gemini Advanced.

Utilizza OverlayConfig

In Android 11 o versioni successive, puoi usare OverlayConfig per e configurare la mutabilità, lo stato predefinito e la priorità degli overlay. Per configurare un overlay, creare o modificare il file che si trova partition/overlay/config/config.xml, dove partition è la partizione di overlay da configurare. Per essere configurato, un overlay deve trovarsi nella Directory overlay/ della partizione in cui è configurato l'overlay. La il seguente codice mostra un esempio 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>"

Il tag <overlay> richiede un attributo package che indica quale overlay pacchetto in fase di configurazione. L'attributo facoltativo enabled controlla se oppure se l'overlay è attivato per impostazione predefinita (il valore predefinito è false). L'opzione facoltativa L'attributo mutable stabilisce se l'overlay è modificabile e può avere lo stato di attivazione è stato modificato in modo programmatico in fase di runtime (il valore predefinito è true). Gli overlay non elencati all'interno di un file di configurazione sono modificabili e disattivati da predefinito.

Precedenza overlay

Quando più overlay sostituiscono le stesse risorse, l'ordine degli overlay viene importanti. Un overlay ha una precedenza maggiore rispetto agli overlay con configurazioni. che precede la propria configurazione. L'ordine di precedenza degli overlay in diversi (dalla minima alla massima precedenza) è la seguente.

  • system
  • vendor
  • odm
  • oem
  • product
  • system_ext
di Gemini Advanced.

Unisci file

L'utilizzo dei tag <merge> consente di unire altri file di configurazione a specificata nel file di configurazione. Attributo path del tag rappresenta il percorso del file da unire rispetto alla directory contenente di configurazione degli overlay.

Utilizza attributi manifest/RRO statici

In Android 10 o versioni precedenti, l'immutabilità e la precedenza degli overlay vengono configurate utilizzando i seguenti attributi del file manifest.

  • android:isStatic. Quando il valore di questo attributo booleano è impostato su true, l'overlay è abilitato per impostazione predefinita ed è immutabile, il che impedisce la disattivazione.

  • android:priority. Il valore di questo attributo numerico (che influisce solo overlay statici) configura la precedenza dell'overlay in caso di più overlay statici gli overlay hanno come target lo stesso valore della risorsa. Un numero più alto indica una maggiore la precedenza.

Il seguente codice mostra un esempio 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>

Modifiche in Android 11

In Android 11 o versioni successive, se un file di configurazione viene in partition/overlay/config/config.xml, gli overlay vengono configurati utilizzando il file, android:isStatic e android:priority non incidono overlay che si trovano nella partizione. La definizione di un file di configurazione di overlay in qualsiasi applica la precedenza della partizione overlay.

Inoltre, Android 11 o versioni successive rimuove la possibilità utilizzare overlay statici per influenzare i valori delle risorse lette durante la creazione dell'installazione. Relativamente al caso d'uso comune in cui si utilizza overlay statici per modificare valore dei valori booleani che configurano lo stato di attivazione dei componenti, utilizza <component-override> Tag SystemConfig (novità su Android 11).

Overlay di debug

Per attivare, disattivare e scaricare manualmente gli overlay, utilizza il seguente overlay della console Cloud.

adb shell cmd overlay

OverlayManagerService utilizza idmap2 per mappare gli ID risorsa nella destinazione agli ID risorsa del pacchetto di overlay. Le mappature degli ID generate vengono memorizzati in /data/resource-cache/. Se l'overlay non funziona correttamente, trova il file idmap corrispondente per l'overlay in /data/resource-cache/, poi esegui questo comando.

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

Questo comando visualizza la mappatura delle risorse come mostrato di seguito.

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