O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

Sobreposições de recursos de tempo de execução (RROs)

Uma sobreposição de recursos de tempo de execução (RRO) é um pacote que altera os valores de recursos de um pacote de destino no tempo de execução. Por exemplo, um aplicativo instalado na imagem do sistema pode mudar seu comportamento com base no valor de um recurso. Em vez de codificar o valor do recurso no tempo de construção, um RRO instalado em uma partição diferente pode alterar os valores dos recursos do aplicativo no tempo de execução.

RROs podem ser habilitados ou desabilitados. Você pode definir programaticamente o estado de ativação / desativação para alternar a capacidade de um RRO de alterar os valores dos recursos. RROs são desativados por padrão (no entanto, RROs estáticos são ativadas por padrão).

Recursos de sobreposição

As sobreposições funcionam mapeando recursos definidos no pacote de sobreposições para recursos definidos no pacote de destino. Quando um aplicativo tenta resolver o valor de um recurso no pacote de destino, o valor do recurso de sobreposição para o qual o recurso de destino está mapeado é retornado.

Configurando o manifesto

Um pacote é considerado um pacote RRO se ele contém um <overlay> tag como um filho do <manifest> tag.

  • O valor dos necessários android:targetPackage especifica atributo o nome do pacote a RRO pretende sobreposição.

  • O valor dos opcionais android:targetName atributo especifica o nome do subconjunto overlayable de recursos do pacote de destino a RRO pretende sobrepor. Se o destino não define um conjunto de recursos sobrepostos, este atributo não deve estar presente.

O seguinte mostra um exemplo de código sobreposição 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>

As sobreposições não podem sobrepor o código, portanto, não podem ter arquivos DEX. Além disso, o android:hasCode atributo do <application > tag no manifesto deve ser definida como false .

Definindo o mapa de recursos

Em Android 11 ou superior, o mecanismo recomendado para definir o mapa de recursos de sobreposição é criar um arquivo no res/xml diretório do pacote de sobreposição, enumerar os recursos de destino que devem ser sobrepostos e respectivos valores de reposição, em seguida, defina o valor do android:resourcesMap atributo do <overlay> tag manifesto para uma referência para o arquivo de mapeamento de recursos.

O seguinte mostra um exemplo de código res/xml/overlays.xml arquivo.

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

O código a seguir mostra um exemplo de manifesto de sobreposição.

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

Construindo o pacote

Android 11 ou superior suporta uma regra de construção Soong para sobreposições que impede ativos Android Embalagem Ferramenta 2 (AAPT2) de tentar configurações Dedupe de recursos com o mesmo valor ( --no-resource-deduping ) e da remoção de recursos sem configurações padrão ( --no-resource-removal ). O código a seguir mostra um exemplo Android.bp arquivo.

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

Resolvendo recursos

Se um recurso de destino ou recurso de sobreposição tiver várias configurações definidas para o recurso que está sendo consultado, o tempo de execução de recursos retornará o valor da configuração que melhor corresponda à configuração do dispositivo. Para determinar qual configuração é a melhor configuração de correspondência, fundir o conjunto das configurações de recursos de sobreposição no conjunto de configurações de recursos alvo e, em seguida, seguir o fluxo resolução de recursos regulares (para detalhes, consulte Como Android encontra o recurso melhor correspondência ).

Por exemplo, se uma sobreposição define um valor para o drawable-en configuração e o alvo define um valor para drawable-en-port , drawable-en-port tem uma melhor correspondência de modo que o valor da configuração alvo drawable-en-port está escolhido em tempo de execução. Para sobrepor todos drawable-en configurações, a sobreposição deve definir um valor para cada drawable-en configuração define as alvo.

As sobreposições podem fazer referência a seus próprios recursos, com comportamentos diferentes entre as versões do Android.

  • No Android 11 ou superior, cada sobreposição tem seu próprio espaço de ID de recurso reservado que não se sobrepõe ao espaço de ID de recurso de destino ou outros espaços de ID de recurso de sobreposição, portanto, as sobreposições que fazem referência a seus próprios recursos funcionam conforme o esperado.

  • Em Android 10 ou inferior, sobreposições e pacotes de destino compartilham o mesmo espaço ID de recursos, o que pode causar colisões e um comportamento inesperado quando eles tentam fazer referência a seus próprios recursos usando o @type/name de sintaxe.

Ativando / desativando sobreposições

Use o OverlayManager API para permitir e sobreposições mutáveis desativar (recuperar o API de interface usando Context#getSystemService(Context.OVERLAY_SERVICE) ). Uma sobreposição pode ser ativado somente pelo pacote tem como alvo ou por um pacote com o android.permission.CHANGE_OVERLAY_PACKAGES permissão. Quando uma sobreposição é habilitada ou desabilitada, os eventos de mudança de configuração se propagam para o pacote de destino e as atividades de destino são reiniciadas.

Restringindo recursos sobrepostos

Em Android 10 ou superior, o <overlayable> tag XML expõe um conjunto de recursos que RROs estão autorizados a sobreposição. No exemplo a seguir res/values/overlayable.xml arquivo, string/foo e integer/bar são recursos utilizados para theming a aparência do dispositivo; para sobrepor esses recursos, uma sobreposição deve visar explicitamente a coleção de recursos sobrepostos por 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>

Um APK pode definir múltiplos <overlayable> tags, mas cada marca deve ter um nome exclusivo dentro do pacote. Por exemplo, é:

  • OK para dois pacotes diferentes para ambos definir <overlayable name="foo"> .

  • Não OK para um único APK ter dois <overlayable name="foo"> blocos.

O código a seguir mostra um exemplo de uma sobreposição no AndroidManifest.xml arquivo.

<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 um aplicativo define um <overlayable> tag, sobrepõe segmentação que app:

  • Deve especificar targetName .

  • Pode sobrepor apenas os recursos listados dentro do <overlayable> tag.

  • Pode ter como alvo apenas um <overlayable> nome.

Você não pode permitir uma sobreposição alvo um pacote que expõe recursos overlayable mas não usa android:targetName para atingir um determinado <overlayable> tag.

Políticas de restrição

Use o <policy> tag para impor restrições sobre os recursos overlayable. Os type especifica atributos que as políticas de uma sobreposição deve cumprir para substituir os recursos incluídos. Os tipos suportados incluem o seguinte.

  • public . Qualquer sobreposição pode substituir o recurso.
  • system . Qualquer sobreposição na partição do sistema pode substituir os recursos.
  • vendor . Qualquer sobreposição na partição do fornecedor pode substituir os recursos.
  • product . Qualquer sobreposição na partição do produto pode substituir os recursos.
  • signature . Qualquer sobreposição assinada com a mesma assinatura do APK de destino pode substituir os recursos.

O seguinte mostra um exemplo de código <policy> tag na res/values/overlayable.xml arquivo.

<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 várias políticas, use barras verticais (|) como caracteres separadores. Quando várias políticas forem especificados, uma sobreposição precisa cumprir apenas uma política para substituir os recursos listados dentro do <policy> tag.

Configurando sobreposições

O Android oferece suporte a diferentes mecanismos para configurar a mutabilidade, o estado padrão e a prioridade das sobreposições, dependendo da versão de lançamento do Android.

  • Dispositivos com o Android 11 ou superior pode usar uma OverlayConfig arquivo ( config.xml ) em vez de atributos de manifesto. Usar um arquivo de sobreposição é o método recomendado para sobreposições.

  • Todos os dispositivos podem usar atributos de manifesto ( android:isStatic e android:priority ) para RROs configure estáticos.

Usando OverlayConfig

Em Android 11 ou superior, você pode usar OverlayConfig para configurar a mutabilidade, estado padrão, e prioridade de sobreposições. Para configurar uma sobreposição, criar ou modificar o arquivo localizado na partition/overlay/config/config.xml , onde partition é a partição da sobreposição para ser configurado. Para ser configurado, uma sobreposição deve residir na overlay/ directório de partição em que a sobreposição é configurado. O seguinte mostra um exemplo 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>"

O <overlay> tag requer um package atributo que indica que pacote de sobreposição está sendo configurado. O opcional enabled controles de atributos ou não a sobreposição é ativado por padrão (o padrão é false ). Os opcionais mutable controles de atributos ou não a sobreposição é mutável e pode ter seu estado habilitado mudou programaticamente em tempo de execução (o padrão é true ). As sobreposições não listadas em um arquivo de configuração são mutáveis ​​e desabilitadas por padrão.

Sobreposição de precedência

Quando várias sobreposições substituem os mesmos recursos, a ordem das sobreposições é importante. Uma sobreposição tem maior precedência do que sobreposições com configurações anteriores à sua própria configuração. A ordem de precedência das sobreposições em diferentes partições (da menor para a maior precedência) é a seguinte.

  • system
  • vendor
  • oem
  • odm
  • product
  • system_ext

Mesclando arquivos

Usando <merge> tag permite a outros arquivos de configuração a serem incorporadas na posição especificada no arquivo de configuração. O path atributo da marca representa o caminho do arquivo para mesclar relativo ao diretório contendo sobreposição de arquivos de configuração.

Usando atributos de manifesto (RROs estáticos)

No Android 10 ou inferior, a imutabilidade e a precedência da sobreposição são configuradas usando os seguintes atributos de manifesto.

  • android:isStatic . Quando o valor desse atributo booleano é definido como true , a sobreposição é ativado por padrão e é imutável, o que impede a sobreposição de ser desativado.

  • android:priority . O valor deste atributo numérico (que afeta apenas sobreposições estáticas) configura a precedência da sobreposição quando várias sobreposições estáticas visam o mesmo valor de recurso. Um número mais alto indica uma precedência mais alta.

O código seguinte mostra um exemplo 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>

Mudanças no Android 11

Em Android 11 ou superior, se um arquivo de configuração está localizado na partition/overlay/config/config.xml , sobreposições são configurados usando esse arquivo e android:isStatic e android:priority não têm um efeito sobre sobreposições localizados na partição. Definir um arquivo de configuração de sobreposição em qualquer partição reforça a precedência da partição de sobreposição.

Além disso, o Android 11 ou superior remove a capacidade de usar sobreposições estáticas para afetar os valores dos recursos lidos durante a instalação do pacote. Para o caso de uso comum de usar sobreposições estáticas para alterar o valor de booleans esse componente configure habilitado estado, use o <component-override> SystemConfig tag (novo no Android 11).

Depurando sobreposições

Para habilitar, desabilitar e descartar as sobreposições manualmente, use o seguinte comando shell do gerenciador de sobreposições.

adb shell cmd overlay

OverlayManagerService usos idmap2 para mapear IDs de recursos no pacote de destino para IDs de recursos no pacote de sobreposição. Os mapeamentos de ID gerados são armazenados em /data/resource-cache/ . Se a sua sobreposição não está funcionando corretamente, encontrar o correspondente idmap arquivo para o seu sobreposição em /data/resource-cache/ , em seguida, execute o seguinte comando.

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

Este comando imprime o mapeamento de recursos conforme mostrado abaixo.

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