Una superposición de recursos en tiempo de ejecución (RRO) es un paquete que cambia los valores de recursos de un paquete de destino en tiempo de ejecución. Por ejemplo, una aplicación instalada en la imagen del sistema puede cambiar su comportamiento según el valor de un recurso. En lugar de codificar el valor del recurso en el momento de la compilación, un RRO instalado en una partición diferente puede cambiar los valores de los recursos de la aplicación en el tiempo de ejecución.
Las RRO se pueden habilitar o deshabilitar. Puede establecer mediante programación el estado de activación / desactivación para alternar la capacidad de una RRO para cambiar los valores de los recursos. RRO están desactivados por defecto (sin embargo, las RRO estáticas están habilitadas por defecto).
Recursos superpuestos
Las superposiciones funcionan mapeando los recursos definidos en el paquete de superposición a los recursos definidos en el paquete de destino. Cuando una aplicación intenta resolver el valor de un recurso en el paquete de destino, se devuelve el valor del recurso de superposición al que está asignado el recurso de destino.
Configurando el manifiesto
Un paquete se considera un paquete RRO si contiene un <overlay>
etiqueta como un hijo de la <manifest>
etiqueta.
El valor de las requeridas
android:targetPackage
atributo especifica el nombre del paquete de la RRO tiene la intención de superposición.El valor de los opcionales
android:targetName
atributo especifica el nombre del subconjunto overlayable de los recursos del paquete de destino la RRO pretende superponer. Si el destino no define un conjunto de recursos superpuestos, este atributo no debería estar presente.
El código siguiente muestra un ejemplo de superposición 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>
Las superposiciones no pueden superponer el código, por lo que no pueden tener archivos DEX. Además, el android:hasCode
atributo de la <application
> tag en el manifiesto se debe establecer en false
.
Definición del mapa de recursos
En Android 11 o superior, el mecanismo recomendado para definir el mapa de recursos de superposición es crear un archivo en el res/xml
directorio del paquete de superposición, enumerar los recursos de destino que debe ser superpuestos y sus valores de reposición, a continuación, establezca el valor de la android:resourcesMap
atributo de la <overlay>
etiqueta de manifiesto para una referencia al archivo de asignación de recursos.
A continuación se muestra un ejemplo de código res/xml/overlays.xml
archivo.
<?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>
El siguiente código muestra un manifiesto de superposición de ejemplo.
<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>
Construyendo el paquete
Android 11 o superior compatible con una regla de construcción Soong para los recubrimientos que impide Android activos Packaging Tool 2 (AAPT2) de intentar configuraciones dedupe de recursos con el mismo valor ( --no-resource-deduping
) y de la eliminación de los recursos sin configuraciones por defecto ( --no-resource-removal
). El siguiente código muestra un ejemplo Android.bp
archivo.
runtime_resource_overlay {
name: "ExampleOverlay",
sdk_version: "current",
}
Resolución de recursos
Si un recurso de destino o recurso de superposición tiene varias configuraciones definidas para el recurso que se está consultando, el tiempo de ejecución de recursos devuelve el valor de la configuración que mejor coincide con la configuración del dispositivo. Para determinar qué configuración es la mejor configuración coincidente, fusionar el conjunto de las configuraciones de recursos de superposición en el conjunto de configuraciones de recursos objetivo y luego seguir el flujo de resolución de recursos ordinarios (para más detalles, consulte Cómo Android encuentra el recurso de mejor coincidencia ).
Por ejemplo, si una superposición define un valor para el drawable-en
la configuración y el destino define un valor para drawable-en-port
, drawable-en-port
tiene un mejor partido de modo que el valor de la configuración de destino drawable-en-port
es elegido en tiempo de ejecución. Para superponer todo drawable-en
configuraciones, la superposición debe definir un valor para cada drawable-en
configuración las define diana.
Las superposiciones pueden hacer referencia a sus propios recursos, con diferentes comportamientos entre las versiones de Android.
En Android 11 o superior, cada superposición tiene su propio espacio de ID de recurso reservado que no se superpone al espacio de ID de recurso de destino ni a otros espacios de ID de recurso superpuesto, por lo que las superposiciones que hacen referencia a sus propios recursos funcionan como se esperaba.
En Android 10 o inferior, superposiciones y paquetes de destino comparten el mismo espacio identificador de recursos, lo que puede provocar colisiones y un comportamiento inesperado cuando intentan hacer referencia a sus propios recursos mediante el
@type/name
sintaxis.
Habilitar / deshabilitar superposiciones
Usar la OverlayManager
API para activar y desactivar las superposiciones mutables (recuperar la API de interfaz utilizando Context#getSystemService(Context.OVERLAY_SERVICE)
). Una superposición sólo se puede activar por el paquete que se dirige o por un paquete con el android.permission.CHANGE_OVERLAY_PACKAGES
permiso. Cuando una superposición está habilitada o deshabilitada, los eventos de cambio de configuración se propagan al paquete de destino y las actividades de destino se reinician.
Restringir recursos superpuestos
En Android 10 o superior, el <overlayable>
etiqueta XML expone un conjunto de recursos que RRO se les permite superposición. En el ejemplo siguiente res/values/overlayable.xml
archivo, string/foo
y integer/bar
son los recursos utilizados para la tematización de la apariencia del dispositivo; para superponer estos recursos, una superposición debe apuntar explícitamente a la colección de recursos superpuestos por nombre.
<!-- 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 puede definir múltiples <overlayable>
etiquetas, pero cada etiqueta debe tener un nombre único dentro del paquete. Por ejemplo, es:
Bien para dos paquetes diferentes para ambos definen
<overlayable name="foo">
.No está mal para un único archivo APK a tener dos
<overlayable name="foo">
bloques.
El siguiente código muestra un ejemplo de una superposición en el AndroidManifest.xml
archivo.
<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>
Cuando una aplicación define un <overlayable>
tag, superposiciones de orientación esa aplicación:
Debe especificar
targetName
.Puede superponer sólo los recursos que aparecen en el
<overlayable>
etiqueta.Pueden dirigirse a un único
<overlayable>
nombre.
No se puede permitir que una superposición dirigidas a un paquete que expone los recursos overlayable pero no utiliza android:targetName
a dirigirse a un determinado <overlayable>
etiqueta.
Políticas restrictivas
Utilice el <policy>
etiqueta para hacer cumplir las restricciones sobre los recursos overlayable. Los type
especifica qué políticas de atributos debe cumplir una superposición a anulan los recursos incluidos. Los tipos admitidos incluyen los siguientes.
-
public
. Cualquier superposición puede anular el recurso. -
system
. Cualquier superposición en la partición del sistema puede anular los recursos. -
vendor
. Cualquier superposición en la partición del proveedor puede anular los recursos. -
product
. Cualquier superposición en la partición del producto puede anular los recursos. -
signature
. Cualquier superposición firmada con la misma firma que el APK de destino puede anular los recursos.
El siguiente código muestra un ejemplo <policy>
etiqueta en el res/values/overlayable.xml
archivo.
<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>
Para especificar varias políticas, utilice barras verticales (|) como caracteres separadores. Cuando se especifican varias políticas, una superposición necesita cumplir sólo una política para anular los recursos que aparecen en el <policy>
etiqueta.
Configurar superposiciones
Android admite diferentes mecanismos para configurar la mutabilidad, el estado predeterminado y la prioridad de las superposiciones según la versión de lanzamiento de Android.
Dispositivos con Android 11 o superior pueden utilizar un
OverlayConfig
archivo (config.xml
) en lugar de atributos manifiestos. El uso de un archivo de superposición es el método recomendado para superposiciones.Todos los dispositivos se pueden utilizar atributos manifiestos (
android:isStatic
yandroid:priority
) a RRO de configuración estática.
Usando OverlayConfig
En Android 11 o superior, puede utilizar OverlayConfig
para configurar la mutabilidad, estado predeterminado, y la prioridad de superposiciones. Para configurar una plantilla, crear o modificar el archivo que se encuentra en la partition/overlay/config/config.xml
, donde partition
es la partición de la superposición para ser configurado. Para ser configurado, una superposición debe residir en la overlay/
directorio de la partición en la que está configurada la plantilla. A continuación se muestra un ejemplo de código de 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>"
La <overlay>
etiqueta requiere un package
atributo que indica cuál es el paquete de superposición se está configurando. La opción enabled
atributo controla si o no el protector está activado por defecto (default es false
). Los opcionales mutable
atributo controla si o no el protector es mutable y puede tener su estado habilitado cambió mediante programación en tiempo de ejecución (por defecto es true
). Las superposiciones que no figuran en un archivo de configuración son mutables y están desactivadas de forma predeterminada.
Precedencia de superposición
Cuando varias superposiciones anulan los mismos recursos, el orden de las superposiciones es importante. Una superposición tiene mayor precedencia que las superposiciones con configuraciones que preceden a su propia configuración. El orden de precedencia de las superposiciones en diferentes particiones (de menor a mayor precedencia) es el siguiente.
-
system
-
vendor
-
oem
-
odm
-
product
-
system_ext
Fusionar archivos
Usando <merge>
etiquetas permite otros archivos de configuración que se combinarán en la posición especificada en el archivo de configuración. La path
atributo de la etiqueta representa la ruta del archivo de fusionar relativa al directorio que contiene los archivos de configuración de superposición.
Uso de atributos de manifiesto (RRO estáticas)
En Android 10 o versiones anteriores, la inmutabilidad y la precedencia de la superposición se configuran mediante los siguientes atributos de manifiesto.
android:isStatic
. Cuando el valor de este atributo booleano se establece entrue
, la superposición está activada por defecto y es inmutable, lo que evita la superposición de ser desactivado.android:priority
. El valor de este atributo numérico (que afecta solo a las superposiciones estáticas) configura la precedencia de la superposición cuando varias superposiciones estáticas tienen como objetivo el mismo valor de recurso. Un número más alto indica una precedencia más alta.
El código siguiente muestra un ejemplo 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>
Cambios en Android 11
En Android 11 o superior, si un archivo de configuración se encuentra en la partition/overlay/config/config.xml
, superposiciones se configuran utilizando ese archivo y android:isStatic
y android:priority
no tienen un efecto sobre las superposiciones situadas en la partición. La definición de un archivo de configuración de superposición en cualquier partición impone la prioridad de la partición de superposición.
Además, Android 11 o superior elimina la capacidad de usar superposiciones estáticas para afectar los valores de los recursos leídos durante la instalación del paquete. Para el caso de uso común de utilizar superposiciones estáticas para cambiar el valor de booleanos que el componente de configuración habilitada estado, utilice el <component-override>
SystemConfig
etiqueta (nuevo en Android 11).
Superposiciones de depuración
Para habilitar, deshabilitar y volcar las superposiciones manualmente, use el siguiente comando de shell del administrador de superposiciones.
adb shell cmd overlay
OverlayManagerService
usos idmap2
para asignar identificadores de recursos en el paquete de destino de ID de los recursos en el paquete de superposición. Las asignaciones de identificación generados se almacenan en /data/resource-cache/
. Si su superposición no está funcionando correctamente, encontrar el correspondiente idmap
archivo para su superposición en /data/resource-cache/
, a continuación, ejecute el siguiente comando.
adb shell idmap2 dump --idmap-path [file]
Este comando imprime la asignación de recursos como se muestra a continuación.
[target res id] - > [overlay res id] [resource name]
0x01040151 -> 0x01050001 string/config_dozeComponent
0x01040152 -> 0x01050002 string/config_dozeDoubleTapSensorType
0x01040153 -> 0x01050003 string/config_dozeLongPressSensorType