Reemplazo de recursos de tiempo de ejecución de Android ---- Práctica de superposición de recursos de tiempo de ejecución

Reimpreso de la solución de diseño de aplicaciones [Car Android] (1): superposición de recursos en tiempo de ejecución

Android ha agregado un mecanismo de superposición dinámica de recursos en tiempo de ejecución (RRO) desde M. Esto es aportado por Sony. El mecanismo de implementación es el que se muestra a continuación: establece un conjunto de tablas de mapeo de ID de recursos en el marco y cambia dinámicamente entre diferentes temas a través de esta tabla de mapeo.
Insertar descripción de la imagen aquí

Práctica de rejuvenecimiento cutáneo RRO

Primero prepare una aplicación que necesita ser rediseñada. Aquí crearemos una nueva aplicación como ejemplo. A continuación llamaremos al nuevo proyecto de aplicación de destino "aplicación de destino". El objetivo es utilizar el mecanismo RRO para reemplazar los valores de color. en la aplicación de destino.

Insertar descripción de la imagen aquí

Paso 1: crear un paquete de recursos y configurar AndroidManifest.xml

Primero, necesitamos crear un nuevo proyecto de aplicación independiente. El propósito de esta aplicación es colocar los archivos de recursos de la "aplicación de destino", a continuación lo llamaremos "paquete de recursos". Aunque es un proyecto de aplicación, no contiene código lógico y solo puede usarse para almacenar archivos de recursos.

Al observar este paso, en realidad creamos dos nuevos proyectos de aplicación, uno es la aplicación de destino y el otro es el paquete de recursos.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.target.overlay.ten">

    <overlay
        android:targetName="ThemeResources"
        android:priority="20"
        android:targetPackage="com.android.target" />

    <application android:hasCode="false"/>

</manifest>

Si el AndroidManifest.xml de un APK contiene <overlay>la etiqueta como <manifest>elemento secundario de la etiqueta, el APK se considerará un "paquete de recursos".

  • [Configuración requerida] android:targetPackage se usa para especificar la "aplicación de destino" que RRO desea reemplazar.
  • [Configuración requerida] android:hasCode debe establecerse en falso. RRO no puede utilizar archivos DEX porque el código no se puede reemplazar.
  • [Configuración no requerida] android:targetName se usa para especificar el nombre del subconjunto de recursos reemplazables de la "aplicación de destino" de RRO. Si la "aplicación de destino" no define un conjunto de recursos alternativo, no es necesario establecer este atributo.
Conjunto de recursos reemplazables

En Android 10 o superior, la "aplicación de destino" puede usar <overlayable>la etiqueta para exponer un conjunto de recursos que permiten el reemplazo de RRO. El reemplazo de RRO no está permitido para recursos que no están expuestos.

<resources>
    <overlayable name="ThemeResources">
        <policy type="public">
            <item type="color" name="purple_200" />
            <item type="color" name="purple_500" />
        </policy>
    </overlayable>
</resources>

Un APK puede definir varias etiquetas, pero cada etiqueta debe tener un nombre único dentro del paquete. Por ejemplo:

  • Se pueden definir dos paquetes de recursos diferentes al mismo tiempo.
  • Un APK no puede tener dos bloques.

Luego debe especificar ThemeResources usando targetName en AndroidManifest.xml del paquete de recursos.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.target.overlay.ten">

    <overlay
        android:targetName="ThemeResources"
        android:targetPackage="com.android.target" />

    <application android:hasCode="false"/>

</manifest>

Cuando la aplicación de destino define <overlayable>la etiqueta, el paquete de recursos <overlay>debe cumplir las siguientes condiciones:

  • Se debe especificar targetName.

  • Solo <overlayable>se pueden reemplazar los recursos enumerados en la etiqueta.

  • Sólo <overlayable>se puede apuntar a un nombre.

Política de restricción

Utilice <policy>etiquetas para imponer restricciones a los recursos reemplazables en la aplicación de destino. typeLas propiedades especifican qué requisitos de política debe cumplir la superposición para reemplazar el recurso contenido. Se admiten los siguientes tipos:

  • público: cualquier superposición puede reemplazar el recurso correspondiente.
  • sistema: cualquier superposición en la partición del sistema reemplaza el recurso correspondiente.
  • proveedor: cualquier superposición en la partición del proveedor reemplaza el recurso correspondiente.
  • producto: cualquier superposición en la partición del producto reemplaza el recurso correspondiente.
  • firma: cualquier superposición firmada con la misma firma que el APK de destino puede reemplazar el recurso correspondiente.
<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 una barra vertical (|) como separador. Si se especifican varias políticas, la superposición solo debe cumplir los requisitos de una política para reemplazar <policy>los recursos enumerados en la etiqueta.

Paso 2: definir el mapeo de recursos

  • Android 10 o inferior
    En Android 10 o inferior, el sistema reemplaza los recursos según sus nombres, por lo que solo necesitamos definir los recursos que deben reemplazarse en el paquete de recursos.

Insertar descripción de la imagen aquí

  • Android 11 o superior
    En Android 11 o superior, Google recomienda crear un archivo en el directorio res/xml del "paquete de recursos" overlays.xmlpara enumerar los valores de recursos de la "aplicación de destino" que deben sobrescribirse y sus valores de reemplazo. .
<?xml version="1.0" encoding="utf-8"?>
<overlay xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 更换颜色 -->
    <item target="color/purple_200" value="#000000"/>
    <item target="color/purple_500" value="#000000"/>
    <item target="color/purple_700" value="#000000"/>
    <item target="color/teal_200" value="#000000"/>
    <item target="color/teal_700" value="#000000"/>
    <item target="color/black" value="#000000"/>
    <item target="color/white" value="#000000"/>
</overlay>

Tenga en cuenta que el color de la etiqueta de destino no tiene la marca @. En realidad, es solo una cadena y no una referencia.

Luego, establezca el valor del atributo android:resourcesMap en el archivo de mapeo de recursos en AndroidManifest.xml del paquete de recursos.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.target.overlay.eleven">

    <overlay
        android:targetName="ThemeResources"
        android:targetPackage="com.android.target"
        android:resourcesMap="@xml/overlays"/>

    <application
        android:hasCode="false"/>

</manifest>

Paso 3: construir el paquete de recursos

El paquete de recursos integrado se puede instalar directamente usando Android Studio cuando estamos depurando, como se muestra a continuación.

  1. Ejecute la aplicación de destino y el paquete de recursos.
  2. Haga clic derecho en el directorio de datos/aplicaciones y seleccione la opción "Sincronizar"

Después de los dos pasos anteriores, habrá dos rutas más en el directorio de datos/aplicación, que representan el apk de la aplicación de destino y el paquete de recursos respectivamente.

Cuando se lanza oficialmente, el "paquete de recursos" se puede publicar en el directorio de proveedor/superposición, y la "aplicación de destino" se puede colocar de manera flexible según las necesidades. Luego reinicie el sistema Android.

Paso 4: habilitar/deshabilitar RRO

RRO se puede habilitar y deshabilitar utilizando la API proporcionada por OverlayManager. OverlayManager no se proporciona en el SDK público de Android. Si usa Gradle para construir el proyecto, debe usar el código fuente de AOSP para compilar un framework.jar e importarlo antes de que pueda usarse. Al mismo tiempo, la firma de la aplicación También necesita usar la firma del sistema Android para convertir la aplicación en una aplicación a nivel de sistema.

OverlayManager manager = MainActivity.this.getSystemService(OverlayManager.class);
OverlayInfo overlayInfo = manager.getOverlayInfo("com.android.target.overlay.ten", UserHandle.CURRENT_OR_SELF);
manager.setEnabled("com.android.target.overlay.ten", !overlayInfo.isEnabled(), UserHandle.CURRENT_OR_SELF);

Después de habilitar o deshabilitar RRO, los eventos de cambio de configuración se propagan a la aplicación de destino y se reinicia la actividad de la aplicación de destino.

Si desea realizar la prueba en el teléfono móvil, puede usar los comandos adb para activar y desactivar RRO.

adb shell cmd overlay enable [com.android.target.overlay.ten] // 开启
adb shell cmd overlay disable [com.android.target.overlay.ten] // 关闭

Manifestación

Documentación oficial

Supongo que te gusta

Origin blog.csdn.net/jxq1994/article/details/130992767
Recomendado
Clasificación