A partir do Android 9 (nível 28 da API), a plataforma restringe quais interfaces de fora do SDK seu app pode usar. Essas restrições são aplicadas sempre que um app se refere a uma interface externa ao SDK ou tenta buscar o identificador dela usando reflexão ou JNI. As limitações foram implementadas para ajudar a melhorar a experiência do usuário e do desenvolvedor e reduzir os riscos de falhas para os usuários e lançamentos de emergência para os desenvolvedores. Para saber mais sobre essa decisão, consulte como reduzir o uso de interfaces externas ao SDK para melhorar a estabilidade (em inglês).
Diferenciar interfaces SDK e não SDK
De um modo geral, as interfaces públicas do SDK são aquelas encontradas documentadas no índice de pacotes do framework Android. O processamento de interfaces externas ao SDK é um detalhe de implementação que a API abstrai. Portanto, essas interfaces estão sujeitas a alterações sem aviso prévio.
Para evitar falhas e comportamentos inesperados, os apps só podem usar as partes oficialmente documentadas das classes no SDK. Isso também significa que não é permitido acessar métodos ou campos que não estejam listados no SDK ao interagir com uma classe usando mecanismos como reflexão.
Listas de APIs não SDK
A cada versão do Android, mais interfaces não SDK são restritas. Sabemos que essas limitações podem afetar o fluxo de trabalho da sua versão e queremos garantir que você tenha as ferramentas para detectar o uso de interfaces de fora do SDK, uma oportunidade de dar feedback e tempo para planejar e se ajustar às novas políticas.
Para minimizar o impacto das restrições de interfaces externas ao SDK no seu fluxo de trabalho de desenvolvimento, essas interfaces são divididas em listas que definem até que ponto o uso é restrito, dependendo de qual nível da API está sendo segmentado. A tabela a seguir descreve cada uma dessas listas:
Lista | Descrição |
---|---|
Lista de bloqueio (blacklist ) |
São interfaces externas ao SDK que não podem ser usadas, independentemente do nível da API de destino do app. Caso seu app tente acessar uma delas, o sistema emitirá um erro. |
Bloqueio condicional (greylist-max-x ) |
A partir do Android 9 (nível 28 da API), cada nível da API tem interfaces não SDK restritas caso sejam a API de destino do app. Essas listas são rotuladas pelo nível máximo da API
( Caso o app tente acessar uma interface restrita no nível da API de destino, o sistema se comportará como se ela estivesse na lista de bloqueio. |
Incompatível (greylist ) |
São interfaces não SDK que ainda não são restritas e podem ser usadas pelo app.
No entanto, elas não são compatíveis e
estão sujeitas a mudanças sem aviso prévio. Pressuponha que essas interfaces serão bloqueadas
condicionalmente em versões futuras do Android por uma
lista max-target-x . |
SDK (whitelist ) |
São interfaces que podem ser usadas livremente e no momento são aceitas como parte do Índice de pacote do framework do Android oficialmente documentado. |
Embora dependendo do nível da API de destino do app ainda seja possível usar algumas interfaces não SDK, o uso de qualquer método ou campo delas sempre implica um alto risco de corromper o app. Se ele depender de interfaces externas, comece a planejar uma migração para opções do SDK ou outras alternativas. Caso você não encontre uma alternativa para deixar de usar a interface não SDK em um recurso no seu app, solicite uma nova API pública.
Determinar a que lista uma interface pertence
As listas de interfaces externas ao SDK são criadas como parte da plataforma. Consulte as seções abaixo para saber mais sobre cada versão do Android.
Android 14 (Beta)
No Android 14, você pode fazer o download do arquivo abaixo que descreve todas as interfaces não SDK e as listas correspondentes:
Arquivo: hiddenapi-flags.csv
Soma de verificação SHA-256: cdd43f463f11ce91786fe94b4e5893dbd5d1b03c784f9e578109daa4d43917ae
Para saber mais sobre as mudanças na lista de APIs não SDK no Android 14, consulte Atualizações para restrições de interface não SDK no Android 14.
Android 13
No Android 13 (nível 33 da API), você pode fazer o download do seguinte arquivo, que descreve todas as interfaces não SDK e as listas correspondentes:
Arquivo: hiddenapi-flags.csv
Soma de verificação SHA-256: 233a277aa8ac475b6df61bffd95665d86aac6eb2ad187b90bf42a98f5f2a11a3
Para saber mais sobre as mudanças na lista de APIs não SDK do Android 13, incluindo sugestões de alternativas públicas para APIs que são bloqueadas condicionalmente nele, consulte Atualizações para restrições de interface não SDK no Android 13.
Android 12
No Android 12 (nível 31 da API), você pode fazer o download do arquivo a seguir que descreve todas as interfaces não SDK e as listas correspondentes:
Arquivo: hiddenapi-flags.csv
Soma de verificação SHA-256: 40674ff4291eb268f86561bf687e69dbd013df9ec9531a460404532a4ac9a761
Para saber mais sobre as mudanças na lista de APIs não SDK no Android 12, incluindo sugestões de alternativas públicas para APIs que são bloqueadas condicionalmente nele, consulte Mudanças na lista do Android 12.
Android 11
No Android 11 (API de nível 30), você pode fazer o download do seguinte arquivo que descreve todas as interfaces não SDK e as listas correspondentes:
Arquivo: hiddenapi-flags.csv
Soma de verificação SHA-256: a19d839f4f61dc9c94960ae977b2e0f3eb30f880ba1ffe5108e790010b477a56
Para saber mais sobre as mudanças na lista de APIs não SDK no Android 11, incluindo sugestões de alternativas públicas para APIs que são bloqueadas condicionalmente nele, consulte Mudanças na lista do Android 11.
Android 10
No Android 10 (API de nível 29), você pode fazer o download do seguinte arquivo que descreve todas as interfaces não SDK e as listas correspondentes:
Arquivo: hiddenapi-flags.csv
Soma de verificação SHA-256: f22a59c215e752777a114bd9b07b0b6b4aedfc8e49e6efca0f99681771c5bfeb
Para saber mais sobre as mudanças na lista de APIs não SDK no Android 10, incluindo sugestões de alternativas públicas para APIs que são bloqueadas condicionalmente nele, consulte Mudanças na lista do Android 10.
Android 9
O seguinte arquivo de texto contém a lista de
APIs não SDK que não são restritas no Android 9 (nível 28 da API): hiddenapi-light-greylist.txt
.
A lista de bloqueio (blacklist
) e a lista de APIs bloqueadas condicionalmente (lista
cinza-escuro) são derivadas no momento da compilação.
Gerar listas do AOSP
Ao trabalhar com o AOSP, você pode gerar um arquivo hiddenapi-flags.csv
que
contenha todas as interfaces externas ao SDK e as listas correspondentes. Para fazer isso,
faça o download da origem do AOSP
e execute o seguinte comando:
m out/soong/hiddenapi/hiddenapi-flags.csv
Depois disso, será possível encontrar o arquivo no seguinte local:
out/soong/hiddenapi/hiddenapi-flags.csv
Comportamento esperado quando as interfaces não SDK restritas são acessadas
A tabela a seguir descreve o comportamento esperado caso o app tente acessar uma interface não SDK incluída na lista de bloqueio.
Meios de acesso | Resultado |
---|---|
Instrução Dalvik referenciando um campo | NoSuchFieldError exibido |
Instrução Dalvik referenciando um método | NoSuchMethodError exibido |
Reflexão usando Class.getDeclaredField() ou Class.getField() |
NoSuchFieldException exibido |
Reflexão usando Class.getDeclaredMethod() , Class.getMethod() |
NoSuchMethodException exibido |
Reflexão usando Class.getDeclaredFields() , Class.getFields() |
Membros externos ao SDK excluídos dos resultados |
Reflexão usando Class.getDeclaredMethods() , Class.getMethods() |
Membros externos ao SDK excluídos dos resultados |
JNI usando env->GetFieldID() |
NULL retornado, NoSuchFieldError exibido |
JNI usando env->GetMethodID() |
NULL retornado, NoSuchMethodError exibido |
Testar se há interfaces que não são do SDK no seu app
Existem vários métodos que você pode usar para testar interfaces externas ao SDK no seu app.
Testar usando um app de depuração
Para testar se há interfaces externas ao SDK, crie e execute um app de depuração em um dispositivo ou emulador com Android 9 (nível 28 da API) ou versão mais recente. Confira se o dispositivo ou emulador que você está usando corresponde ao nível da API de destino do seu app.
Ao fazer testes no app, o sistema imprime uma mensagem de registro caso seu app acesse determinadas interfaces externas ao SDK. É possível inspecionar as mensagens de registro do app para encontrar os seguintes detalhes:
- A classe, o nome e o tipo declarantes (no formato usado pelo ambiente de execução do Android).
- Os meios de acesso: veiculação, reflexão ou JNI.
- A que lista a interface externa pertence.
É possível usar o adb logcat
para acessar essas mensagens de registro, que aparecem sob
o PID do app em execução. Por exemplo, pode haver uma entrada assim no registro:
Accessing hidden field Landroid/os/Message;->flags:I (light greylist, JNI)
Testar usando a API StrictMode
Também é possível testar se há interfaces externas ao SDK usando a API StrictMode
. Use o método
detectNonSdkApiUsage
para ativar. Depois de ativar a API StrictMode
, você pode receber um
retorno de chamada para cada uso de uma interface externa usando um penaltyListener
,
em que é possível implementar o tratamento personalizado. O objeto Violation
fornecido no
retorno de chamada deriva de Throwable
, e o stack trace incluído fornece o
contexto do uso.
Testar usando a ferramenta veridex
Também é possível ativar a ferramenta de análise estática veridex no seu APK. A ferramenta veridex examina toda a base de código do APK, incluindo quaisquer bibliotecas de terceiros, e relata qualquer uso de interfaces externas ao SDK que encontrar.
Limitações da ferramenta veridex incluem o seguinte:
- Não é possível detectar invocações por meio do JNI.
- É possível detectar apenas um subconjunto de invocações por meio da reflexão.
- A análise para caminhos de código inativos é limitada a verificações no nível da API.
- Ele só pode ser executado em máquinas compatíveis com as instruções SSE4.2 e POPCNT.
Windows
Os binários nativos do Windows não são fornecidos, mas você pode ativar a ferramenta veridex no Windows executando os binários do Linux com o Windows Subsystem for Linux (WSL). Antes de seguir as etapas nesta seção, instale o WSL e escolha o Ubuntu como a distribuição Linux.
Após a instalação do Ubuntu, inicie um terminal Ubuntu e siga estas etapas:
- Faça o download da ferramenta veridex no repositório de pré-versões do ambiente de execução do Android.
- Extraia o conteúdo do arquivo
appcompat.tar.gz
. - Na pasta extraída, localize o arquivo
veridex-linux.zip
e descompacte-o. Navegue até a pasta descompactada e execute o seguinte comando, em que
your-app.apk
é o APK que você quer testar:./appcompat.sh --dex-file=your-app.apk
macOS
Para ativar a ferramenta veridex no macOS, siga estas etapas:
- Faça o download da ferramenta veridex no repositório de pré-versões do ambiente de execução do Android.
- Extraia o conteúdo do arquivo
appcompat.tar.gz
. - Na pasta extraída, localize o arquivo
veridex-mac.zip
e descompacte-o. Navegue até a pasta descompactada e execute o seguinte comando, em que
/path-from-root/your-app.apk
é o caminho para o APK que você quer testar, começando do diretório raiz do sistema:./appcompat.sh --dex-file=/path-from-root/your-app.apk
Linux
Para ativar a ferramenta veridex no Linux, siga estas etapas:
- Faça o download da ferramenta veridex no repositório de pré-versões do ambiente de execução do Android.
- Extraia o conteúdo do arquivo
appcompat.tar.gz
. - Na pasta extraída, localize o arquivo
veridex-linux.zip
e descompacte-o. Navegue até a pasta descompactada e execute o seguinte comando, em que
your-app.apk
é o APK que você quer testar:./appcompat.sh --dex-file=your-app.apk
Testar usando a ferramenta lint do Android Studio
Sempre que você cria um app no Android Studio, a ferramenta lint inspeciona o código em busca de possíveis problemas. Se o app usar interfaces não SDK, você verá erros ou avisos do build, dependendo da lista a que essas interfaces pertencem.
Também é possível executar a ferramenta lint na linha de comando ou executar inspeções manualmente em um projeto, uma pasta ou um arquivo específico.
Testar usando o Play Console
Ao fazer upload do app para uma faixa de teste no Play Console, o app é automaticamente testado para possíveis problemas, e um relatório de pré-lançamento é gerado. Se o app usar interfaces não SDK, um erro ou aviso será exibido no relatório de pré-lançamento, dependendo da lista a que elas pertencem.
Para saber mais, consulte a seção "Compatibilidade do Android" em Usar relatórios de pré-lançamento para identificar problemas.
Solicitar uma nova API pública
Caso você não encontre uma alternativa para deixar de usar uma interface externa ao SDK para um recurso no seu app, é possível solicitar uma nova API pública criando uma solicitação de recurso no Issue Tracker.
Ao criar uma solicitação de recurso, forneça as informações abaixo:
- Qual API sem suporte você está usando no momento, incluindo o descritor
completo que aparece na mensagem do logcat
Accessing hidden ...
. - Por que você precisa usar essas APIs, incluindo detalhes sobre o recurso de alto nível para que a API é necessária, e não apenas detalhes de baixo nível.
- Por que as APIs públicas do SDK relacionadas são insuficientes para seus objetivos.
- Quaisquer outras alternativas que você tenha tentado e por que elas não funcionaram.
Ao fornecer esses detalhes na sua solicitação de recurso, você aumenta a probabilidade de uma nova API pública ser concedida.
Mais perguntas
Esta seção inclui algumas respostas para outras perguntas que os desenvolvedores realizam com frequência:
Perguntas gerais
Como o Google pode ter certeza de que capturará as necessidades de todos os apps por meio do issuetracker?
Criamos as listas iniciais do Android 9 (nível 28 da API) por meio da análise estática de apps, que foi complementada usando os seguintes métodos:
- Teste manual dos principais apps do Google Play e de outras fontes
- Relatórios internos
- Coleta automática de dados de usuários internos
- Relatórios de visualização do desenvolvedor
- Análise estática adicional que foi projetada para incluir, de modo conservador, mais falsos positivos.
À medida que avaliamos as listas para cada nova versão, consideramos o uso da API e o feedback dos desenvolvedores por meio do rastreador de problemas.
Como posso ativar o acesso a interfaces que não são do SDK?
É possível ativar o acesso a interfaces externas em dispositivos de desenvolvimento usando comandos adb para alterar a política de aplicação da API. Os comandos que você usa variam, dependendo do nível da API. Esses comandos não exigem um dispositivo com acesso root.
- Android 10 (API de nível 29) ou mais recente
Para ativar o acesso, use o seguinte comando adb:
adb shell settings put global hidden_api_policy 1
Para redefinir a política de aplicação da API para as configurações padrão, use o seguinte comando:
adb shell settings delete global hidden_api_policy
- Android 9 (API de nível 28)
Para ativar o acesso, use os seguintes comandos adb:
adb shell settings put global hidden_api_policy_pre_p_apps 1
adb shell settings put global hidden_api_policy_p_apps 1
Para redefinir a política de aplicação da API para as configurações padrão, use os seguintes comandos:
adb shell settings delete global hidden_api_policy_pre_p_apps
adb shell settings delete global hidden_api_policy_p_apps
Você pode definir o número inteiro na política de aplicação da API como um dos seguintes valores:
- 0: desativa todas as detecções de interfaces não SDK. O uso dessa configuração desativa
todas as mensagens de registro para uso de interface externa ao SDK e impede que você teste seu
app usando a API
StrictMode
. Essa configuração não é recomendada. - 1: ativa o acesso a todas as interfaces externas ao SDK, mas imprime mensagens de registro com
avisos para qualquer uso desse tipo de interface. O uso dessa configuração também permite
testar seu app usando a API
StrictMode
. - 2: não permite o uso de interfaces não SDK incluídas na lista de bloqueio ou bloqueadas condicionalmente para o nível da API de destino.
Perguntas sobre listas de interface não SDK
Onde encontro as listas de APIs não SDK na imagem do sistema?
Elas são codificadas nos bits de sinalização de acesso a campo e método nos arquivos dex da plataforma. Não há arquivo separado na imagem do sistema que contenha essas listas.
As APIs não SDK são as mesmas em dispositivos de OEM diferentes que tenham a mesma versão do Android?
Os OEMs podem adicionar suas próprias interfaces à lista de bloqueio, mas não podem removê-las das listas de APIs não SDK do AOSP. O CDD impede essas mudanças, e os testes do CTS garantem que o ambiente de execução do Android aplique a lista.
Perguntas sobre a compatibilidade de apps relacionados
Existe alguma restrição em interfaces não NDK no código nativo?
O SDK do Android inclui interfaces Java. A plataforma começou a restringir o acesso a interfaces não NDK para códigos C/C++ nativos no Android 7 (nível 26 da API). Para mais informações, consulte como melhorar a estabilidade com restrições de símbolo C/C++ privado no Android N.
Existe algum plano para restringir a manipulação de arquivos dex2oat ou DEX?
Não temos planos ativos para restringir o acesso ao binário dex2oat, mas não pretendemos que o formato de arquivo DEX seja estável ou uma interface pública além das partes que são publicamente especificadas no formato executável Dalvik. Reservamo-nos o direito de modificar ou eliminar o dex2oat e as partes não especificadas do formato DEX a qualquer momento. Os arquivos derivados produzidos pelo dex2oat, como ODEX (também conhecido como OAT), VDEX e CDEX, são formatos não especificados.
E se um SDK de terceiros crucial (por exemplo, um ofuscador) não puder evitar o uso de interfaces que não são do SDK, mas se comprometer a manter a compatibilidade com futuras versões do Android? O Android poderá renunciar aos requisitos de compatibilidade nesse caso?
Não temos planos de dispensar os requisitos de compatibilidade para SDKs específicos. Se um desenvolvedor de SDK puder manter compatibilidade somente dependendo das interfaces nas listas incompatíveis (anteriormente cinzas), ele precisará começar a planejar a migração para interfaces SDK ou outras alternativas e solicitar uma nova API pública sempre que não puder encontrar uma alternativa ao uso de uma interface não SDK.
As restrições de interface externa ao SDK se aplicam a todos os apps, incluindo apps do sistema e de terceiros, e não somente apps de terceiros?
Sim, mas isentamos apps assinados com a chave da plataforma e alguns
apps de imagem do sistema. Essas exceções se aplicam somente a apps que fazem parte da imagem do sistema
ou a apps de imagem do sistema atualizados. A lista é destinada somente a apps
criados com base nas APIs da plataforma privada, não nas APIs do SDK
(em que LOCAL_PRIVATE_PLATFORM_APIS := true
).