Ferramentas de framework de compatibilidade

O Android 11 introduziu novas ferramentas para desenvolvedores para testar e depurar seu app em relação às mudanças de comportamento nas versões mais recentes da plataforma Android. Essas ferramentas fazem parte de um framework de compatibilidade que permite aos desenvolvedores de apps ativar e desativar alterações interruptivas usando opções do desenvolvedor ou ADB individualmente. Use essa flexibilidade ao se preparar para direcionar à versão estável mais recente da API e ao testar seu app com a versão de pré-lançamento da próxima versão do Android.

Quando você usa as ferramentas do framework de compatibilidade, a plataforma Android adapta automaticamente a lógica interna para que não seja necessário mudar a targetSDKVersion nem recompilar o app para realizar testes básicos. Como as mudanças são alternáveis individualmente, você pode isolar, testar e depurar uma mudança de comportamento por vez ou desativar uma única mudança que esteja causando problemas se precisar testar outra coisa primeiro.

Como identificar quais mudanças estão ativadas

Quando uma mudança de comportamento está ativada, ela pode afetar a forma como seu app acessa as APIs da plataforma impactadas por essa mudança. Você pode verificar quais mudanças de comportamento estão ativadas usando as opções do desenvolvedor, o logcat ou os comandos ADB.

Identificar mudanças ativadas usando as opções do desenvolvedor

Figura 1. Tela de mudanças na compatibilidade de apps nas opções do desenvolvedor.

Você pode conferir quais mudanças estão ativadas e ativar ou desativar essas mudanças nas opções do desenvolvedor de um dispositivo. Para acessar essas opções, siga estas etapas:

  1. Se as opções do desenvolvedor ainda não estiverem ativadas, ative-as.
  2. Abra o app Configurações do seu dispositivo e navegue até Sistema > Avançado > Opções do desenvolvedor > Mudanças na compatibilidade de apps.
  3. Selecione seu app na lista.

Cada mudança de comportamento geralmente pertence a uma destas duas categorias:

  • Mudanças que afetam todos os apps executados nessa versão do Android, independentemente da targetSdkVersion do app.

    Essas mudanças são ativadas por padrão no framework de compatibilidade e são listadas na IU na seção Mudanças ativadas por padrão.

  • Mudanças que afetam apenas apps voltados a determinadas versões do Android. Como essas mudanças afetam apenas os apps voltados a uma versão específica do Android, elas também são chamadas de mudanças controladas pela targetSDKVersion.

    Essas mudanças serão ativadas por padrão no framework de compatibilidade se o app for direcionado a uma versão mais recente do que a da API listada. Por exemplo, uma mudança de comportamento controlada por targetSDKVersion no Android 13 (nível 33 da API) seria listada na interface como uma seção intitulada Ativadas para a targetSdkVersion >=33. Em algumas versões anteriores do Android, esta seção é intitulada "Ativada após o SDK API_LEVEL".

Você também notará uma seção na figura 1 chamada Mudanças desativadas por padrão. As mudanças que se enquadram nessa seção podem servir para vários fins. Antes de ativar essas mudanças, leia a descrição da mudança na lista de frameworks de compatibilidade dessa versão do Android.

Identificar mudanças ativadas usando o logcat

Para cada mudança de comportamento, na primeira vez durante o processo do app quando o app chama a API afetada, o sistema gera uma mensagem de logcat como esta:

D CompatibilityChangeReporter: Compat change id reported: 194833441; UID 10265; state: ENABLED

Cada mensagem de logcat inclui as seguintes informações:

ID da mudança
Indica qual mudança está afetando o app. Esse valor é mapeado para uma das mudanças de comportamento listadas na tela Mudanças na compatibilidade de apps (consulte a figura 1). Neste exemplo, 194833441 é mapeado para NOTIFICATION_PERM_CHANGE_ID.
UID
Indica qual app é afetado pela mudança.
State

Indica se a mudança está afetando o app.

O estado pode ser um destes valores:

State Significado
ENABLED A mudança está ativada e vai afetar o comportamento do app se ele usar as APIs que foram modificadas.
DISABLED

A mudança está desativada e não vai afetar o app.

Observação: se essa mudança estiver desativada porque a targetSDKVersion do app está abaixo do limite necessário, a mudança será ativada por padrão quando o app aumentar o valor da targetSDKVersion para ser direcionado a uma versão mais recente.

LOGGED A mudança está sendo registrada pelo framework de compatibilidade, mas não pode ser ativada ou desativada. Apesar disso, ela ainda pode afetar o comportamento do app. Para mais informações, consulte a descrição da mudança na lista do framework de compatibilidade dessa versão do Android. Em muitos casos, esses tipos de mudanças são experimentais e podem ser ignorados.

Identificar mudanças ativadas usando ADB

Execute o seguinte comando ADB para ver o conjunto completo de mudanças (ativas e desativadas) em todo o dispositivo:

adb shell dumpsys platform_compat

A saída lista as seguintes informações para cada mudança:

ID da mudança
Um identificador exclusivo para essa mudança de comportamento. Por exemplo, 194833441.
Nome
O nome dessa mudança de comportamento. Por exemplo, NOTIFICATION_PERM_CHANGE_ID.
critérios de targetSDKVersion

Por qual targetSDKVersion a mudança é controlada (se houver).

Por exemplo, se essa mudança estiver ativada apenas para apps destinados à versão 33 ou mais recente do SDK, a saída será enableAfterTargetSdk=32. Se a mudança não for controlada por targetSDKVersion, enableAfterTargetSdk=0 será gerada.

Modificações de pacotes

O nome de cada pacote em que o estado padrão da mudança (ativado ou desativado) foi substituído.

Por exemplo, se essa for uma mudança ativada por padrão, o nome do pacote do app será listado se você tiver desativado a mudança usando as opções do desenvolvedor ou o ADB. Nesse caso, o resultado seria:

packageOverrides={com.my.package=false}

As mudanças controladas pelo targetSDKVersion podem ser ativadas ou desativadas por padrão, de modo que a lista de pacotes pode incluir instâncias de true ou false, dependendo de cada uma das targetSDKVersion do app. Por exemplo:

packageOverrides={com.my.package=true, com.another.package=false}

Saiba mais sobre mudanças específicas

A lista completa de mudanças de comportamento no framework de compatibilidade está incluída como parte da documentação de cada versão do Android. Consulte os links abaixo para mais informações, dependendo da versão do Android em que o app está sendo testado:

Quando ativar ou desativar as mudanças

O principal objetivo do framework de compatibilidade é oferecer a você controle e flexibilidade para testar seu app com versões mais recentes do Android. Esta seção descreve algumas estratégias que podem ser usadas para determinar quando ativar ou desativar mudanças durante o teste e a depuração do app.

Quando desativar as mudanças

A decisão de quando desativar as mudanças geralmente depende de a mudança ser controlada pela targetSDKVersion ou não.

Mudanças ativadas para todos os apps

As mudanças que afetam todos os apps são ativadas por padrão para uma versão específica da plataforma, independente da targetSDKVersion do app. Dessa forma, é possível conferir se o app é afetado quando executado nessa versão da plataforma.

Por exemplo, se você estiver se preparando para direcionar ao Android 14 (nível 34 da API), poderá começar instalando o app em um dispositivo que executa o Android 14 e testar o app usando os fluxos de trabalho de teste típicos. Se encontrar problemas no app, desative a mudança que está causando o problema e continue testando se há outros problemas.

Como essas mudanças podem afetar todos os apps, independente da targetSDKVersion, em geral é preciso testar e atualizar o app quanto a essas mudanças antes que elas sejam controladas pela targetSDKVersion. Isso ajuda a garantir que os usuários não tenham uma experiência prejudicada no app quando atualizarem o dispositivo para uma nova versão da plataforma.

Você também precisa priorizar o teste dessas mudanças porque não é possível desativá-las ao usar um build de lançamento público do Android. O ideal é realizar testes dessas mudanças para cada versão do Android enquanto a versão está disponível na prévia.

Mudanças controladas pela targetSDKVersion

Se o app for direcionado a uma targetSDKVersion específica, todas as mudanças controladas por essa versão serão ativadas por padrão. Portanto, à medida que você muda a targetSDKVersion do app para uma nova versão, o app começa a ser afetado por muitas mudanças de uma só vez.

Como o app pode ser afetado por mais de uma dessas mudanças, talvez seja necessário desativar algumas individualmente durante o teste e a depuração do app.

Quando ativar as mudanças

As mudanças controladas por uma targetSDKVersion específica são desativadas por padrão sempre que um app está direcionado a uma versão do SDK anterior à versão controlada. Normalmente, ao se preparar para direcionar a uma nova targetSdkVersion, você vai precisar testar e depurar uma lista de mudanças de comportamento no seu app.

Por exemplo, é possível testar o app em relação a uma série de mudanças de plataforma na próxima targetSdkVersion. Usando opções do desenvolvedor ou comandos ADB, é possível ativar e testar cada mudança controlada uma por uma, em vez de mudar o manifesto do app e ativar todas as mudanças de uma vez. Esse controle extra pode ajudar a testar as mudanças de forma isolada e evitar a depuração e atualização de várias partes do app ao mesmo tempo.

Depois de ativar uma mudança, você pode testar e depurar o app usando fluxos de trabalho de teste típicos. Se você encontrar problemas, verifique seus registros para ajudar a determinar a causa. Se não estiver claro se o problema é causado por uma mudança de plataforma ativada, tente desativar essa mudança e testar novamente essa área do app.

Ativar ou desativar mudanças

O framework de compatibilidade permite ativar ou desativar cada mudança usando as opções do desenvolvedor ou comandos ADB. Como a ativação ou desativação de mudanças pode fazer com que o app falhe ou desative mudanças de segurança importantes, existem algumas restrições de quando você pode ativar ou desativar mudanças.

Ativar ou desativar mudanças usando as opções do desenvolvedor

Use as opções do desenvolvedor para ativar ou desativar mudanças. Para encontrar as opções, siga estas etapas:

  1. Se as opções do desenvolvedor ainda não estiverem ativadas, ative-as.
  2. Abra o app de configurações do seu dispositivo e navegue até Sistema > Avançado > Opções do desenvolvedor > Mudanças na compatibilidade de apps.
  3. Selecione seu app na lista.
  4. Na lista de mudanças, encontre a mudança que você quer ativar ou desativar e toque na chave.

    Lista de mudanças que podem ser ativadas ou desativadas

Ativar ou desativar mudanças usando o ADB

Para ativar ou desativar uma mudança usando ADB, execute um dos seguintes comandos:

adb shell am compat enable (CHANGE_ID|CHANGE_NAME) PACKAGE_NAME
adb shell am compat disable (CHANGE_ID|CHANGE_NAME) PACKAGE_NAME

Transmita ou a CHANGE_ID (por exemplo, 194833441) ou CHANGE_NAME (por exemplo, NOTIFICATION_PERM_CHANGE_ID) e o PACKAGE_NAME do seu app.

Também é possível usar o comando abaixo para redefinir uma mudança para o estado padrão, removendo qualquer substituição que você tenha definido usando o ADB ou as opções do desenvolvedor:

adb shell am compat reset (CHANGE_ID|CHANGE_NAME) PACKAGE_NAME

Restrições sobre a alternância de mudanças

Por padrão, cada mudança de comportamento é ativada ou desativada. As mudanças que afetam todos os apps são ativadas por padrão. Outras mudanças são controladas por um targetSdkVersion. Essas mudanças são ativadas por padrão quando um app é direcionado à versão correspondente do SDK ou uma mais recente e são desativadas por padrão quando um app é direcionado a uma versão do SDK anterior à versão controlada. Ao ativar ou desativar uma mudança, você modifica o estado padrão dela.

Para impedir que o framework de compatibilidade seja usado de forma maliciosa, há algumas restrições sobre quando você pode ativar ou desativar as mudanças. Se você pode ou não ativar uma mudança depende do tipo de mudança, se o app é depurável e do tipo de build em execução no dispositivo. A tabela a seguir descreve quando é possível ativar ou desativar diferentes tipos de mudanças:

Tipo de build App não depurável App depurável
Todas as mudanças Mudanças controladas por targetSDKVersion Todas as outras mudanças
Visualização do desenvolvedor ou build Beta Não é possível ativar/desativar Pode alternar Pode alternar
Build pública de usuário Não é possível ativar/desativar Pode alternar Não é possível ativar/desativar