Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

Superposiciones de recursos en tiempo de ejecución (RRO)

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 y android: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 en true , 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