Un overlay delle risorse di runtime (RRO) è un pacchetto che modifica i valori delle risorse di un pacchetto di destinazione in fase di runtime. Ad esempio, un'app installata sull'immagine di sistema potrebbe modificare il proprio comportamento in base al valore di una risorsa. Anziché codificare in modo permanente il valore della risorsa in fase di compilazione, un RRO installato su una partizione diversa può modificare i valori delle risorse dell'app in fase di runtime.
Le RRO possono essere attivate o disattivate. Puoi impostare a livello di programmazione lo stato di attivazione/disattivazione per attivare/disattivare la possibilità di una RRO di modificare i valori delle risorse. Le RRO sono disattivate per impostazione predefinita (tuttavia, le RRO statiche sono attive per impostazione predefinita).
Risorse di overlay
Le sovrapposizioni funzionano mappando le risorse definite nel pacchetto di sovrapposizione alle risorse definite nel pacchetto di destinazione. Quando un'app tenta di risolvere il valore di una risorsa nel pacchetto di destinazione, viene restituito il valore della risorsa di overlay a cui è mappata la risorsa di destinazione.
Configurare il manifest
Un pacchetto è considerato un pacchetto RRO se contiene un tag <overlay> come
elemento secondario del tag <manifest>.
Il valore dell'attributo obbligatorio
android:targetPackagespecifica il nome del pacchetto che l'RRO intende sovrapporre.Il valore dell'attributo facoltativo
android:targetNamespecifica il nome del sottoinsieme di risorse sovrapponibili del pacchetto di destinazione che l'RRO intende sovrapporre. Se la destinazione non definisce un insieme di risorse sovrapponibili, questo attributo non deve essere presente.
Il seguente codice mostra un esempio di overlay AndroidManifest.xml.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.e>xampl<e.overlay"
application andro>id:ha<sCode="false" /
overlay android:targetPackage="com.example.target"
an>d<roid:targ>etName="OverlayableResources"/
/manifest
Gli overlay non possono sovrapporsi al codice, quindi non possono avere file DEX. Inoltre, l'attributo
android:hasCode del tag <application> nel manifest deve essere
impostato su false.
Definisci la mappa delle risorse
In Android 11 o versioni successive, il meccanismo consigliato per
definire la mappa delle risorse di overlay consiste nel creare un file nella directory res/xml
del pacchetto di overlay, enumerare le risorse di destinazione che devono essere
sovrapposte e i relativi valori di sostituzione, quindi impostare il valore dell'attributo
android:resourcesMap del tag manifest <overlay> su un riferimento
al file di mappatura delle risorse.
Il seguente codice mostra un esempio di file res/xml/overlays.xml.
<?xml version="1.0" encodin>g<="utf-8"?
overlay xmlns:android="http://schemas.andr>oid.c<om/apk/res/android"
!-- Overlays string/config1 and string/conf>ig2 w<ith the same resource. --
item target="string/>confi<g1" value="@string/overlay1" /
item >target<="string/config2" value="@string/overl>ay1&q<uot; /
!-- Overlays string/config3 with the string &q>uot;ye<s". --
item target="string/config3" value=">;@and<roid:string/yes" /
!-- Overlays string/config>4 with< the string "Hardcoded string". --
item >targe<t="string/config4" value="H>a<rdcoded >string" /
!-- Overlays integer/config5 with the integer "42". --
item target="integer/config5" value="42" /
/overlay
Il seguente codice mostra un esempio di manifest di overlay.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.e>xampl<e.overlay"
application andro>id:ha<sCode="false" /
overlay android:targetPackage="com.example.target"
android:targetName="OverlayableResources"
> < > android:resourcesMap="@xml/overlays"/
/manifest
Crea il pacchetto
Android 11 o versioni successive supporta una regola di build Soong per
le overlay che impedisce ad Android Asset Packaging Tool 2 (AAPT2) di tentare di
rimuovere le configurazioni duplicate delle risorse con lo stesso valore
(--no-resource-deduping) e di rimuovere le risorse senza configurazioni
predefinite (--no-resource-removal). Il seguente codice mostra un esempio
di file Android.bp.
runtime_resource_overlay {
name: "ExampleOverlay",
sdk_version: "current",
}
Risolvi le risorse
Se una risorsa di destinazione o una risorsa di overlay ha più configurazioni definite per la risorsa di cui viene eseguita la query, l'ambiente di runtime delle risorse restituisce il valore della configurazione che corrisponde meglio alla configurazione del dispositivo. Per determinare quale configurazione corrisponde meglio, unisci l'insieme delle configurazioni delle risorse di overlay all'insieme delle configurazioni delle risorse di destinazione, quindi segui il normale flusso di risoluzione delle risorse (per i dettagli, consulta Come Android trova la risorsa che corrisponde meglio).
Ad esempio, se una sovrapposizione definisce un valore per la configurazione drawable-en e la destinazione definisce un valore per drawable-en-port, drawable-en-port ha una corrispondenza migliore, quindi il valore della configurazione di destinazione drawable-en-port viene scelto in fase di runtime. Per sovrapporre tutte le configurazioni drawable-en, la sovrapposizione
deve definire un valore per ogni configurazione drawable-en definita dalla destinazione.
Gli overlay possono fare riferimento alle proprie risorse, con comportamenti diversi tra le versioni di Android.
In Android 11 o versioni successive, ogni overlay ha il proprio spazio ID risorsa riservato che non si sovrappone allo spazio ID risorsa di destinazione o ad altri spazi ID risorsa di overlay, quindi gli overlay che fanno riferimento alle proprie risorse funzionano come previsto.
In Android 10 o versioni precedenti, le overlay e i pacchetti di destinazione condividono lo stesso spazio ID risorsa, il che può causare conflitti e comportamenti imprevisti quando tentano di fare riferimento alle proprie risorse utilizzando la sintassi
@type/name.
Attivare/disattivare gli overlay
Le overlay possono essere attivate/disattivate manualmente e a livello di programmazione.
Disattivare o attivare manualmente le overlay
Per attivare e verificare manualmente un RRO, esegui:
adb shell cmd overlay enable --user current com.example.carrro
adb shell cmd overlay list --user current | grep -i com.example com.example.carrroIn questo modo viene attivato l'RRO per l'utente di sistema (userId = 0) proprietario di SystemUI.
Questa istruzione non influisce sulle app avviate dall'utente in primo piano
(userId = 10). Per attivare l'RRO per l'utente in primo piano, utilizza il
parametro -–user 10:
adb shell cmd overlay enable --user 10 com.example.carrroAttivare o disattivare le sovrapposizioni a livello di programmazione
Utilizza l'API OverlayManager per attivare e disattivare le sovrapposizioni modificabili (recupera l'interfaccia API utilizzando Context#getSystemService(Context.OVERLAY_SERVICE)). Una sovrapposizione può essere attivata solo dal pacchetto a cui è destinata o da un pacchetto con l'autorizzazione android.permission.CHANGE_OVERLAY_PACKAGES. Quando una sovrapposizione viene
attivata o disattivata, gli eventi di modifica della configurazione si propagano al pacchetto di destinazione
e le attività di destinazione vengono riavviate.
Limitare le risorse sovrapponibili
In Android 10 o versioni successive, il tag XML <overlayable> espone un insieme di risorse
che gli RRO possono sovrapporre. Nel seguente esempio
di file res/values/overlayable.xml, string/foo e integer/bar sono risorse
utilizzate per la personalizzazione dell'aspetto del dispositivo; per sovrapporre queste risorse, una sovrapposizione
deve scegliere come target in modo esplicito la raccolta di risorse sovrapponibili in base al nome.
<!-- The collection of resources for theming the appearance of the device -->
<overlayable name="ThemeResou>rces&quo<t;
policy typ>e="public&q<uot;
item type=&q>uot;string"< name="foo/" /
> i<tem typ>e="inte<ger" na>me="bar/" /
/policy
...
/overlayable
Un APK può definire più tag <overlayable>, ma ogni tag deve avere un nome univoco all'interno del pacchetto. Ad esempio, è:
È possibile che due pacchetti diversi definiscano entrambi
<overlayable name="foo">.Non è consentito che un singolo APK abbia due blocchi
<overlayable name="foo">.
Il seguente codice mostra un esempio di overlay nel file AndroidManifest.xml.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.my>.theme.o<verlay"
application andro>id:hasCo<de="false" /
!-- This overlay will override t>he Theme<Resources resources --
overlay android:targetPackage="android&q>u<ot; andro>id:targetName="ThemeResources"
/manifest
Quando un'app definisce un tag <overlayable>, gli overlay che hanno come target l'app:
Deve specificare
targetName.Può sovrapporre solo le risorse elencate all'interno del tag
<overlayable>.Può scegliere come target un solo nome
<overlayable>.
Non puoi attivare un overlay che ha come target un pacchetto che espone risorse sovrapponibili, ma non utilizza android:targetName per scegliere come target un tag <overlayable> specifico.
Limitare le norme
Utilizza il tag <policy> per applicare restrizioni alle risorse sovrapponibili. L'attributo
type specifica quali criteri deve soddisfare un overlay per eseguire l'override
delle risorse incluse. I tipi supportati includono i seguenti.
public. Qualsiasi overlay può sostituire la risorsa.system. Qualsiasi overlay sulla partizione di sistema può sovrascrivere le risorse.vendor. Qualsiasi overlay sulla partizione del fornitore può eseguire l'override delle risorse.product. Qualsiasi overlay sulla partizione del prodotto può sostituire le risorse.oem. Qualsiasi overlay sulla partizione OEM può eseguire l'override delle risorse.odm. Qualsiasi overlay sulla partizione odm può eseguire l'override delle risorse.signature. Qualsiasi overlay firmato con la stessa firma dell'APK di destinazione può ignorare le risorse.actor. Qualsiasi overlay firmato con la stessa firma dell'APK attore può ignorare le risorse. L'attore è dichiarato nel tag named-actor nella configurazione del sistema.config_signature. Qualsiasi overlay firmato con la stessa firma dell'APK overlay-config può sostituire le risorse. overlay-config è dichiarato nel tag overlay-config-signature nella configurazione di sistema.
Il seguente codice mostra un esempio di tag <policy> nel file
res/values/overlayable.xml.
<overlayable name="ThemeResou>rces<"
policy type>="v<endor"
item type=&>quot<;string>&quo<t; name="foo" /
/pol>icy
p<olicy type="product|signat>ure"<;
item type="stri>ng&q<uot; na>m<e="bar&>quot; /
item type="string" name="baz" /
/policy
/overlayable
Per specificare più criteri, utilizza le barre verticali (|) come caratteri separatori.
Quando vengono specificate più norme, una sovrapposizione deve soddisfarne solo una
per ignorare le risorse elencate nel tag <policy>.
Configurare gli overlay
Android supporta diversi meccanismi per configurare la modificabilità, lo stato predefinito e la priorità delle sovrapposizioni a seconda della versione di Android.
I dispositivi con Android 11 o versioni successive possono utilizzare un file
OverlayConfig(config.xml) anziché gli attributi del manifest. L'utilizzo di un file di overlay è il metodo consigliato per gli overlay.Tutti i dispositivi possono utilizzare gli attributi manifest (
android:isStaticeandroid:priority) per configurare gli RRO statici.
Utilizza OverlayConfig
In Android 11 o versioni successive, puoi utilizzare OverlayConfig per configurare la mutabilità, lo stato predefinito e la priorità delle sovrapposizioni. Per configurare
una sovrapposizione, crea o modifica il file che si trova in
partition/overlay/config/config.xml, dove partition è la partizione della
sovrapposizione da configurare. Per essere configurato, un overlay deve risiedere nella
directory overlay/ della partizione in cui è configurato. Il
seguente codice mostra un esempio di product/overlay/config/config.xml.
<config>
<merge path="OEM-common-rros-config.x>ml&qu<ot; /
overlay package="com.oem.overlay.device" mutable=&quo>t;fal<se" enabled="true" /
overlay packag>e<=">com.oem.green.theme" enabled="true" /
/config"
Il tag <overlay> richiede un attributo package che indica quale pacchetto di overlay
viene configurato. L'attributo facoltativo enabled controlla se
l'overlay è attivato per impostazione predefinita (il valore predefinito è false). L'attributo facoltativo
mutable controlla se l'overlay è modificabile e se il suo stato di attivazione può essere
modificato a livello di programmazione in fase di runtime (il valore predefinito è true).
Gli overlay non elencati in un file di configurazione sono modificabili e disattivati
per impostazione predefinita.
Priorità dell'overlay
Quando più overlay sostituiscono le stesse risorse, l'ordine degli overlay è importante. Un overlay ha una precedenza maggiore rispetto agli overlay con configurazioni che precedono la propria configurazione. L'ordine di precedenza degli overlay in diverse partizioni (dalla precedenza minima a quella massima) è il seguente.
systemvendorodmoemproductsystem_ext
Unire file
L'utilizzo dei tag <merge> consente di unire altri file di configurazione nella posizione
specificata nel file di configurazione. L'attributo path del tag
rappresenta il percorso del file da unire rispetto alla directory contenente
i file di configurazione di overlay.
Utilizzare gli attributi del manifest/RRO statici
In Android 10 o versioni precedenti, l'immutabilità e la precedenza dell'overlay vengono configurate utilizzando i seguenti attributi del manifest.
android:isStatic. Quando il valore di questo attributo booleano è impostato sutrue, l'overlay è abilitato per impostazione predefinita ed è immutabile, il che impedisce la disattivazione dell'overlay.android:priority. Il valore di questo attributo numerico (che influisce solo sulle overlay statiche) configura la precedenza dell'overlay quando più overlay statiche hanno come target lo stesso valore della risorsa. Un numero più alto indica una priorità maggiore.
Il seguente codice mostra un esempio di AndroidManifest.xml.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.e>xampl<e.overlay"
application andro>id:ha<sCode="false" /
overlay android:targetPackage="com.example.target"
android:isStatic="t>r<ue"<>/span>
android:priority="5"/
/manifest
Modifiche in Android 11
In Android 11 o versioni successive, se un file di configurazione si trova in partition/overlay/config/config.xml, gli overlay vengono configurati utilizzando quel file e android:isStatic e android:priority non hanno effetto sugli overlay che si trovano nella partizione. La definizione di un file di configurazione overlay in una
partizione impone la precedenza della partizione overlay.
Inoltre, Android 11 o versioni successive rimuove la possibilità
di utilizzare overlay statici per influire sui valori delle risorse lette durante l'installazione
del pacchetto. Per il caso d'uso comune di utilizzo di overlay statici per modificare il
valore dei booleani che configurano lo stato di attivazione dei componenti, utilizza il
tag <component-override> SystemConfig (novità di Android
11).
Overlay di debug
Per attivare, disattivare e scaricare manualmente le sovrapposizioni, utilizza il seguente comando shell di gestione delle sovrapposizioni.
adb shell cmd overlayL'utilizzo di enable senza specificare un utente influisce sull'utente corrente, ovvero
sull'utente di sistema (userId = 0), proprietario della UI di sistema. Questa operazione non influisce
sull'utente in primo piano (userId = 10), proprietario delle app. Per attivare l'RRO per
l'utente in primo piano, utilizza il parametro –-user 10:
adb shell cmd overlay enable --user 10 com.example.carrroOverlayManagerService utilizza idmap2 per mappare gli ID risorsa nel pacchetto di destinazione
agli ID risorsa nel pacchetto di overlay. Le mappature degli ID generate
vengono memorizzate in /data/resource-cache/. Se l'overlay non funziona correttamente, trova
il file idmap corrispondente per l'overlay in /data/resource-cache/, poi
esegui il comando seguente.
adb shell idmap2 dump --idmap-path [file]Questo comando stampa il mapping 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