Os apps publicados no Google Play precisam oferecer suporte a arquiteturas de 64 bits (link em inglês). A adição de uma versão de 64 bits do seu app proporciona melhorias de desempenho e faz com que ele possa ser executado em hardware com 64 bits.
As etapas abaixo garantem que seu app de 32 bits ofereça suporte a dispositivos de 64 bits.
Avaliar o app
Se o app usa apenas código escrito na linguagem de programação Java ou Kotlin, incluindo bibliotecas ou SDKs, ele oferece suporte a dispositivos de 64 bits. Caso seu app use código nativo ou se você não tem certeza disso, avalie o app.
Verificação rápida de status
Acesse o Play Console e confira se as versões atuais são compatíveis.
O Play Console também vai mostrar avisos que se aplicam às suas versões de rascunho se houver algum problema relacionado ao requisito de 64 bits. A imagem abaixo é um exemplo.
Se um alerta aparecer, consulte as etapas abaixo para oferecer suporte a dispositivos de 64 bits.
O app usa código nativo?
Seu app usa código nativo se ele:
- usa qualquer código C/C++ (nativo);
- vincula-se a qualquer biblioteca nativa de terceiros;
- é feito por um criador de apps de terceiros que usa bibliotecas nativas.
O app inclui bibliotecas de 64 bits?
Inspecione a estrutura do seu arquivo APK. Quando criado, o APK é empacotado com as bibliotecas nativas necessárias para o app. Elas são armazenadas em várias pastas com base na ABI. O app não precisa oferecer suporte a todas as arquiteturas de 64 bits, mas para cada arquitetura nativa de 32 bits com suporte, é necessário incluir a de 64 bits correspondente.
Para a arquitetura ARM, as bibliotecas de 32 bits ficam em armeabi-v7a. O equivalente para 64 bits é arm64-v8a.
No caso da arquitetura x86, procure x86 para 32 bits e x86_64 para 64 bits.
Confira se há bibliotecas nativas nas duas pastas. Em resumo:
Plataforma | Pasta de bibliotecas de 32 bits | Pasta de bibliotecas de 64 bits |
---|---|---|
ARM | lib/armeabi-v7a
|
lib/arm64-v8a
|
x86 | lib/x86
|
lib/x86_64
|
Dependendo do seu app, os conjuntos de bibliotecas em cada pasta não necessariamente serão os mesmos. O objetivo é garantir a execução correta do app em um ambiente de 64 bits.
Em um caso comum, um APK ou pacote criado para arquiteturas de 32 e 64 bits tem pastas para as duas ABIs, cada uma com um conjunto correspondente de bibliotecas nativas. Se ele não oferece suporte a 64 bits, você provavelmente só encontra uma pasta para a ABI de 32 bits.
Procurar bibliotecas nativas usando o APK Analyzer
O APK Analyzer é uma ferramenta que permite avaliar vários aspectos de um APK criado. Use esse recurso para encontrar bibliotecas nativas e garantir a presença das bibliotecas de 64 bits.
- Acesse o Android Studio e abra qualquer projeto.
No menu, selecione Build > Analyze APK….
Escolha o APK que você quer avaliar.
Confira se há algum arquivo ".so" na pasta lib. Se não houver nenhum, seu app vai oferecer suporte a dispositivos de 64 bits, e nenhuma outra ação será necessária. Se você encontrar armeabi-v7a ou x86, isso indica que há bibliotecas de 32 bits.
Verifique se há arquivos ".so" semelhantes na pasta arm64-v8a ou x86_64.
Se você não tiver bibliotecas arm64-v8a ou x86_64, atualize seu processo de build para começar a criar e empacotar esses artefatos no seu APK.
Se as duas bibliotecas já estiverem sendo empacotadas, teste o app em um hardware de 64 bits.
Procurar bibliotecas nativas descompactando APKs
Os APKs são estruturados como arquivos ZIP. Com a linha de comando ou qualquer outra ferramenta de extração, descompacte o arquivo APK. Dependendo da ferramenta de extração, talvez seja necessário renomeá-lo como .zip.
Em seguida, procure os arquivos extraídos e siga a orientação acima para determinar se o app oferece suporte a dispositivos de 64 bits. Execute o exemplo abaixo na linha de comando:
:: Command Line
> zipinfo -1 YOUR_APK_FILE.apk | grep \.so$
lib/armeabi-v7a/libmain.so
lib/armeabi-v7a/libmono.so
lib/armeabi-v7a/libunity.so
lib/arm64-v8a/libmain.so
lib/arm64-v8a/libmono.so
lib/arm64-v8a/libunity.so
Observe nesse exemplo a presença de bibliotecas armeabi-v7a e arm64-v8a. Isso significa que o app oferece suporte a arquiteturas de 64 bits.
Criar o app com bibliotecas de 64 bits
As instruções abaixo descrevem como criar bibliotecas de 64 bits. Essas etapas abrangem apenas o código de criação e as bibliotecas que você pode criar com base na origem.
Se você tiver bibliotecas ou SDKs externos, verifique se está usando as versões de 64 bits. Para isso, siga as etapas acima. Entre em contato com o proprietário do SDK ou da biblioteca se uma versão de 64 bits não estiver disponível e leve isso em consideração ao planejar o suporte a dispositivos de 64 bits.
Criar com o Android Studio ou o Gradle
Como a maioria dos projetos do Android Studio usa o Gradle como sistema de build de base, esta seção se aplica aos dois casos. Para ativar builds do seu código nativo, basta adicionar arm64-v8a e/ou x86_64 (dependendo de quais arquiteturas vão ter suporte) à configuração ndk.abiFilters no arquivo "build.gradle" do app:
Groovy
// Your app's build.gradle plugins { id 'com.android.app' } android { compileSdkVersion 27 defaultConfig { appId "com.google.example.64bit" minSdkVersion 15 targetSdkVersion 28 versionCode 1 versionName "1.0" ndk.abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64' // ...
Kotlin
// Your app's build.gradle plugins { id("com.android.app") } android { compileSdkVersion(27) defaultConfig { appId = "com.google.example.64bit" minSdkVersion(15) targetSdkVersion(28) versionCode = 1 versionName = "1.0" ndk { abiFilters += listOf("armeabi-v7a","arm64-v8a","x86","x86_64") } // ...
Criar com o CMake
Caso seu app seja criado com o CMake, você poderá gerar versões para ABIs de 64 bits transmitindo arm64-v8a para o parâmetro "-DANDROID_ABI":
:: Command Line
> cmake -DANDROID_ABI=arm64-v8a … or
> cmake -DANDROID_ABI=x86_64 …
Essa opção não tem efeito quando se usa
externalNativeBuild
. Veja a seção
Criar com o Gradle.
Criar com o ndk-build
Caso seu app seja criado com o ndk-build, você poderá gerar versões para
ABIs de 64 bits modificando o arquivo Application.mk
com a variável APP_ABI
:
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
Essa opção não tem efeito quando se usa
externalNativeBuild
. Veja a seção
Criar com o Gradle.
Portabilidade de código de 32 bits para 64 bits
Caso seu código já esteja sendo executado no computador ou no iOS,
você não precisa fazer nenhum trabalho extra para o Android. Se esta for a primeira vez que seu código foi criado para
um sistema de 64 bits, o principal problema que você vai precisar resolver é que os ponteiros não se encaixam mais
em tipos inteiros de 32 bits, como int
.
Atualize o código que armazena ponteiros em tipos como int
, unsigned
ou
uint32_t
. Em sistemas Unix, long
corresponde ao tamanho do ponteiro, mas isso não
acontece no Windows. Então, use os tipos de revelação de intenção uintptr_t
ou
intptr_t
. Use o tipo ptrdiff_t
para armazenar a diferença entre dois
ponteiros.
Prefira sempre os tipos inteiros de largura fixa específicos definidos em
<stdint.h>
aos
tipos tradicionais, como int
ou long
, mesmo para elementos que não sejam ponteiros.
Use as flags do compilador mostradas abaixo para capturar casos em que seu código faz a conversão incorretamente entre ponteiros e números inteiros:
-Werror=pointer-to-int-cast
-Werror=int-to-pointer-cast
-Werror=shorten-64-to-32
Classes Java com campos int
que contêm ponteiros para objetos C/C++ têm
o mesmo problema. Procure jint
na origem JNI e
mude para long
na parte em Java e jlong
na parte em C++.
Declarações implícitas de funções são muito mais perigosas para código de 64 bits. O C/C++
presume que o tipo de retorno de uma função declarada implicitamente (ou seja, uma
função de que o compilador não tenha encontrado uma declaração) é int
. Se o
tipo de retorno real da sua função for um ponteiro, isso vai funcionar bem em um sistema de 32 bits
em que o ponteiro se encaixa em um int. No entanto, em um sistema de 64 bits,
o compilador vai eliminar a metade de cima do ponteiro. Exemplo:
// This function returns a pointer:
// extern char* foo();
// If you don't include a header that declares it,
// when the compiler sees this:
char* result = foo();
// Instead of compiling that to:
result = foo();
// It compiles to something equivalent to:
result = foo() & 0xffffffff;
// Which will then cause a SIGSEGV if you try to dereference `result`.
A flag do compilador abaixo transforma avisos implícitos de declaração de função em erros para que você possa encontrar e corrigir esse problema mais facilmente:
-Werror=implicit-function-declaration
Se você tem um conversor inline, reescreva-o ou use uma implementação simples de C/C++.
Se você tiver tamanhos codificados de tipos (8 ou 16 bytes, por exemplo), substitua-os
pela expressão sizeof(T)
equivalente, como sizeof(void*)
.
Se for preciso compilar condicionalmente um código diferente para 32 bits e 64 bits,
use o #if defined(__LP64__)
para diferenças genéricas entre 32 e 64 bits ou __arm__
,
__aarch64__
(arm64), __i386__
(x86) e __x86_64__
para as arquiteturas
específicas com suporte do Android.
Ajuste as strings de formato para funções como printf
ou scanf
, já que
os especificadores tradicionais de formato não permitem especificar tipos de 64 bits
de uma forma correta para dispositivos de 32 bits e de 64 bits. As macros PRI
e SCN
em
<inttypes.h>
resolvem esse problema. Já PRIxPTR
e SCNxPTR
servem para ler/gravar indicadores hex,
e PRId64
e SCNd64
leem/gravam valores de 64 bits de maneira portátil.
Ao mudar, pode ser necessário usar 1ULL
para ter uma constante de 64 bits em vez de usar 1
,
que é apenas de 32 bits.
Evitar aumento de tamanho com o Android App Bundle
O acréscimo da compatibilidade com arquitetura de 64 bits ao seu app pode aumentar o tamanho do seu APK. É altamente recomendável que você use o recurso Android App Bundle para minimizar o impacto sobre o tamanho da inclusão de código nativo de 32 e 64 bits no mesmo APK.
Desenvolvedores de jogos
Atualmente, os três mecanismos mais usados que oferecem suporte a 64 bits:
- Unreal desde 2015
- Cocos2d desde 2015
- Unity desde 2018
Desenvolvedores de Unity
Fazer upgrade para versões compatíveis
O Unity oferece suporte a 64 bits nas versões 2018.2 e 2017.4.16.
Se você está usando uma versão do Unity que não oferece suporte a 64 bits, determine a versão para que pretende fazer upgrade. Siga os guias (em inglês) fornecidos pelo Unity para migrar seu ambiente, garantindo que o app seja atualizado para uma versão que possa criar bibliotecas de 64 bits. O Unity recomenda que você faça upgrade para a última versão LTS do editor para ter acesso aos recursos e atualizações mais recentes.
Confira uma tabela que descreve as várias versões do Unity e o que você deve fazer:
Versão do Unity | Oferece suporte a 64 bits? | Ação recomendada |
---|---|---|
2020.x |
✔️ |
As configurações do build precisam gerar bibliotecas de 64 bits. |
2019.x |
✔️ |
As configurações do build precisam gerar bibliotecas de 64 bits. |
2018.4 (LTS) |
✔️ |
As configurações do build precisam gerar bibliotecas de 64 bits. |
2018.3 |
✔️ |
As configurações do build precisam gerar bibliotecas de 64 bits. |
2018.2 |
✔️ |
As configurações do build precisam gerar bibliotecas de 64 bits. |
2018.1 |
➖ |
Tem compatibilidade experimental com 64 bits. |
2017.4 (LTS) |
✔️ |
Compatível a partir da versão 2017.4.16. As configurações do build precisam gerar bibliotecas de 64 bits. |
2017.3 |
✖️ |
Faça upgrade para a versão compatível com 64 bits. |
2017.2 |
✖️ |
Faça upgrade para a versão compatível com 64 bits. |
2017.1 |
✖️ |
Faça upgrade para a versão compatível com 64 bits. |
<=5.6 |
✖️ |
Faça upgrade para a versão compatível com 64 bits. |
Mudar configurações de criação para produzir bibliotecas de 64 bits
Caso esteja usando uma versão do Unity que oferece suporte a bibliotecas de 64 bits do Android, você pode gerar uma versão de 64 bits do app ajustando as configurações do build. Use o back-end de IL2CPP (link em inglês) com scripts. Para configurar seu projeto do Unity e compilar uma arquitetura de 64 bits, faça o seguinte:
- Acesse Build Settings e confirme que você está criando para Android.
Verifique se o símbolo do Unity está ao lado de Android na seção Platform.
- Se o símbolo do Unity não estiver ao lado da plataforma Android, selecione Android e clique em Switch Platform.
Clique em Player settings.
Navegue até Player Settings Panel > Settings for Android > Other settings > Configuration.
Configure o Scripting Backend como IL2CPP.
Marque a caixa de seleção Target Architecture > ARM64.
Continue criando como de costume.
A criação para ARM64 exige que todos os seus recursos sejam criados especificamente para essa plataforma. Siga as orientações do Unity (em inglês) para reduzir o tamanho do APK e use o recurso Android App Bundle para evitar esse aumento de tamanho.
Compliance com vários APKs e 64 bits
Se você estiver usando o suporte a vários APKs do Google Play para publicar seu app, saiba que a conformidade com o requisito de 64 bits é avaliada no nível da versão. No entanto, o requisito de 64 bits não se aplica a APKs ou pacotes de apps que não sejam distribuídos para dispositivos com o Android 9 Pie ou versões mais recentes.
Se um dos seus APKs estiver marcado como não conforme, mas for mais antigo e não puder
atender ao requisito, adicione um atributo maxSdkVersion="27"
ao elemento
uses-sdk
no manifesto desse APK. O APK não vai ser entregue a dispositivos com o
Android 9 Pie ou versões mais recentes e vai permitir a conformidade.
Compliance com RenderScript e 64 bits
Caso seu app use o RenderScript e tenha sido criado com uma versão mais antiga
das ferramentas do Android, você pode ter problemas de conformidade com 64 bits. Com ferramentas
de build anteriores à 21.0.0, o compilador pode gerar bitcode em um arquivo
.bc
externo. Esses arquivos .bc
legados não são mais compatíveis
com arquiteturas de 64 bits, então a presença do arquivo no APK causa
o problema de conformidade.
Para resolver o problema, remova todos os arquivos .bc
do seu projeto, faça upgrade do
ambiente para build-tools-21.0.0
ou uma versão mais recente e defina a
renderscriptTargetApi
no Android Studio como 21 ou mais recente para instruir o compilador a não emitir mais arquivos .bc
. Em seguida,
recrie seu app, inspecione os arquivos .bc
e faça upload para o Play Console.
Testar o app em hardware de 64 bits
A versão de 64 bits do seu app deve oferecer a mesma qualidade e o mesmo conjunto de recursos da versão de 32 bits. Teste seu app para garantir que os usuários dos dispositivos de 64 bits mais recentes tenham uma ótima experiência.
Dispositivos apenas de 64 bits
Sempre que possível, recomendamos testar o app em um ambiente de 64 bits usando uma destas opções:
Google Pixel com uma imagem de sistema exclusiva para 64 bits
Para facilitar o desenvolvimento e o teste de apps, fornecemos imagens especiais do sistema com um ambiente exclusivamente de 64 bits para alguns dispositivos Pixel. Essas imagens de 64 bits são fornecidas junto de imagens do sistema padrão de fábrica para versões de pré-lançamento do Android.
Android 14 (Beta)
Para instalar uma imagem exclusiva para 64 bits do Android 14, consulte a seção de imagens exclusivas para 64 bits na página de downloads.
Assim como imagens de fábrica do sistema, é possível instalar uma imagem do Android 14 exclusiva para 64 bits no dispositivo usando o app Android Flash Tool ou atualizando o dispositivo manualmente.
Android 13 (QPR3 Beta 3.2)
Para instalar uma imagem exclusiva para 64 bits do Android 13 QPR3, consulte a seção de imagens exclusivas para 64 bits na página de downloads.
Assim como as imagens do sistema de fábrica, é possível instalar uma imagem do Android 13 exclusiva para 64 bits no dispositivo usando o app Android Flash Tool ou atualizando o dispositivo manualmente.
Android Emulator
No Android 12 (nível 31 da API) e versões mais recentes, as imagens do sistema do Android Emulator são exclusivas para 64 bits. Crie um Dispositivo virtual Android (AVD, na sigla em inglês) usando uma imagem do sistema com o Android 12 (nível 31 da API) ou versão mais recente para acessar um ambiente exclusivo para 64 bits e testar apps.
Outras opções de dispositivos
Se você não tem um desses dispositivos ou não consegue usar o Android Emulator, sua melhor opção é utilizar um dispositivo compatível com 64 bits, como um Google Pixel ou outros dispositivos principais recentes de outros fabricantes.
Instalar e testar o app
A maneira mais fácil de testar seu APK é instalar o app usando o Android Debug
Bridge (adb). Na maioria dos casos,
você pode fornecer --abi
como um parâmetro para indicar quais
bibliotecas vão ser instaladas no dispositivo. Isso faz com que o app seja instalado apenas com
as bibliotecas de 64 bits.
:: Command Line
# A successful install:
> adb install --abi armeabi-v7a YOUR_APK_FILE.apk
Success
# If your APK does not have the 64-bit libraries:
> adb install --abi arm64-v8a YOUR_APK_FILE.apk
adb: failed to install YOUR_APK_FILE.apk: Failure [INSTALL_FAILED_NO_MATCHING_ABIS: Failed to extract native libraries, res=-113]
# If your device does not support 64-bit, an emulator, for example:
> adb install --abi arm64-v8a YOUR_APK_FILE.apk
ABI arm64-v8a not supported on this device
Depois de concluir a instalação, teste o app como normalmente faria para garantir que a qualidade seja igual à da versão de 32 bits.
Verificar problemas de compatibilidade conhecidos
Durante o teste, confira se o app tem os problemas descritos a seguir, que afetam apps em 64 bits. Mesmo que o app não dependa das bibliotecas afetadas diretamente, isso pode acontecer com bibliotecas e SDKs de terceiros nas dependências do app.
SoLoader
Se você estiver usando o SDK do carregador de código nativo SoLoader, atualize para v0.10.4 ou mais recente. Se o app usa SDKs que dependem do SoLoader, atualize também para a versão estável mais recente dos SDKs afetados.
O SoLoader v0.9.0 e versões anteriores presumem que bibliotecas do sistema estejam presentes em
/vendor/lib:/system/lib
. Esse bug não aparece em dispositivos como o Pixel
7, em que o caminho existe, mas essa suposição causa falhas em dispositivos que
só têm bibliotecas do sistema em /vendor/lib64:/system/lib64
.
Para mais informações sobre como corrigir esse e outros problemas causados pelo SoLoader, consulte a resposta correspondente na Central de Ajuda do Google.
OpenSSL
Se você está usando a biblioteca OpenSSL, atualize para a OpenSSL 1.1.1i ou versão mais recente. Se o app usa SDKs que fornecem comunicação por HTTPS ou outros SDKs que dependem do OpenSSL, atualize também para a versão mais recente do SDK que usa uma versão mais nova do OpenSSL. Entre em contato com o provedor do SDK, se não houver uma versão disponível.
A função ARMv8.3 PAC permite a integridade do fluxo de controle assistido por hardware ao autenticar ponteiros no momento da execução. Versões mais antigas do OpenSSL usam essa função incorretamente, causando falhas no momento da execução em todos os dispositivos com processadores baseados em ARMv8.3a e versões mais recentes.
Para mais informações sobre como corrigir esse e outros problemas causados pelo OpenSSL, consulte a resposta correspondente na Central de Ajuda do Google.
BTI
O ARMv8.5 e versões mais recentes usam instruções de destino de ramificação (BTIs, na sigla em inglês) para ajudar na proteção contra ataques JOP. Versões mais antigas de SDKs de ofuscação que se ramificam em deslocamentos aleatórios de bibliotecas criadas com BTI podem causar falhas no app. Como as instruções são codificadas como HINTs, esse bug não acontece em dispositivos que não são compatíveis com BTIs (links em inglês).
Publicar
Quando você achar que seu app está pronto, publique-o normalmente. Como sempre, continue seguindo as práticas recomendadas para implantar o app. Aconselhamos que você use as faixas de teste fechado para lançar o app a um número limitado de usuários e garantir que a qualidade dele seja consistente.
Assim como ao lançar uma atualização importante, teste o app completamente em dispositivos compatíveis com 64 bits antes da publicação para um público maior.