Suporte a tamanhos de página de 16 KB

Historicamente, o Android só oferece suporte a tamanhos de página de memória de 4 KB, o que desempenho de memória do sistema otimizado para a quantidade média de memória total que dispositivos Android normalmente tiveram. A partir do Android 15, o AOSP oferece suporte dispositivos configurados para usar um tamanho de página de 16 KB (16 KB) dispositivos). Se o app usa alguma biblioteca NDK diretamente ou indiretamente por meio de um SDK, você precisará recriar seu aplicativo para que ele funcionam nesses dispositivos de 16 KB.

À medida que os fabricantes continuam a construir dispositivos com quantidades na memória física (RAM), a maioria desses dispositivos adotará 16 KB tamanhos de página maiores) para otimizar o desempenho do dispositivo. Adicionando o suporte a dispositivos com tamanho de página de 16 KB permite que seu app seja executado nesses dispositivos. e ajuda seu app a se beneficiar do desempenho associado melhorias. Sem a recompilação, os apps podem não funcionar em dispositivos de 16 KB quando forem colocados em produção em versões futuras do Android.

Para ajudar você a adicionar a compatibilidade com seu app, oferecemos orientações sobre como verificar caso seu app seja afetado, como recriar o app (se aplicável) e como testá-lo na em um ambiente de 16 KB usando emuladores (incluindo o Android 15); imagens do sistema para o Android Emulator).

Benefícios e ganhos de desempenho

Os dispositivos configurados com tamanhos de página de 16 KB usam um pouco mais de memória em média, mas também têm várias melhorias de desempenho para o sistema e os apps:

  • Tempos de inicialização do app mais rápidos enquanto o sistema está sob pressão de memória: 3,16% mais baixos em média, com melhorias mais significativas (até 30%) em alguns apps testados.
  • Redução do consumo de energia durante o lançamento do app: redução média de 4,56%
  • Lançamento mais rápido da câmera: 4,48% mais rápido em média e 6,60% mais rápido em média
  • Tempo de inicialização do sistema melhorado: melhoria de 8% (aproximadamente 950 milissegundos) em média

Essas melhorias são baseadas nos testes iniciais, e os resultados em dispositivos reais provavelmente serão diferentes. Forneceremos análises adicionais de ganhos em potencial para apps à medida que continuarmos nossos testes.

Verificar se o app é afetado

Se o app usar algum código nativo, recompile o app com suporte a dispositivos de 16 KB. Se você não tiver certeza se o app usa código nativo, use o APK Analyzer para identificar se há algum código nativo e verifique o alinhamento dos segmentos ELF para encontrar bibliotecas compartilhadas.

Se o app usa apenas código escrito na linguagem de programação Java ou Kotlin, incluindo bibliotecas ou SDKs, ele já oferece suporte a dispositivos de 16 KB. No entanto, recomendamos que você teste seu app em um ambiente de 16 KB para verificar se não há regressões inesperadas no comportamento do app.

O app usa código nativo?

Seu app usa código nativo se uma das seguintes condições se aplicar:

  • Seu app usa qualquer código C/C++ (nativo). Se o app usa o Android NDK, ele usa código nativo.
  • O app é vinculado a qualquer biblioteca nativa ou dependência de terceiros (como SDKs) que as use.
  • O app é criado por um criador de apps de terceiros que usa bibliotecas nativas no dispositivo.

Identificar bibliotecas nativas usando o APK Analyzer

O APK Analyzer é uma ferramenta que permite avaliar vários aspectos de um APK criado. Para identificar se o app usa código nativo ou bibliotecas, siga estas etapas:

  1. Abra o Android Studio, clique em File > Open e escolha qualquer projeto.
  2. Na barra de menus, clique em Build > Analyze APK….

    Opção de menu do Studio Build para iniciar o APK
Analyzer

  3. Escolha o APK que você quer analisar.

  4. Procure na pasta lib, que hospeda arquivos de objeto compartilhado (.so), se houver. Se houver arquivos de objeto compartilhados, o app vai usar código nativo. Se nenhum arquivo de objeto compartilhado estiver presente ou se não houver uma pasta lib, o app não vai usar código nativo.

    Visualização do APK Analyzer mostrando que arquivos de objeto compartilhados estão
presentes

Verificar o alinhamento de segmentos ELF para bibliotecas compartilhadas

Para qualquer biblioteca compartilhada, verifique se os segmentos ELF dela estão alinhados corretamente usando o alinhamento ELF de 16 KB. Se você estiver desenvolvendo no Linux ou no macOS, use o script check_elf_alignment.sh, conforme descrito na próxima seção. Também é possível usar as ferramentas de linha de comando diretamente.

Use o script check_elf_alignment.sh (Linux ou macOS)

Siga estas etapas para verificar o alinhamento dos segmentos ELF usando o script check_elf_alignment.sh:

  1. Salve o script check_elf_alignment.sh em um arquivo.

  2. Execute o script no arquivo APK do app:

    check_elf_alignment.sh APK_NAME.apk
    

    O script gera ALIGNED ou UNALIGNED para todas as bibliotecas compartilhadas arm64-v8a.

  3. Se alguma biblioteca compartilhada arm64-v8a ou x86_64 estiver UNALIGNED, será necessário atualizar o pacote dessas bibliotecas, recompilar o app e fazer o teste novamente seguindo as etapas desta seção.

Usar ferramentas de linha de comando diretamente

Siga estas etapas para verificar o alinhamento de segmentos ELF usando ferramentas de linha de comando diretamente:

  1. Verifique se o Android SDK Build-Tools versão 35.0.0 ou mais recente e o Android NDK estão instalados usando o SDK Manager no Android Studio ou a ferramenta de linha de comando sdkmanager.
  2. Extraia o arquivo APK do app:

    Linux ou macOS

    unzip APK_NAME.apk -d /tmp/my_apk_out
    

    Windows (PowerShell)

    Expand-Archive -Path .\APK_NAME.apk -DestinationPath ~\tmp\my_apk_out
    
  3. No diretório temporário em que você extraiu o arquivo APK, verifique o conteúdo do diretório lib para arquivos de objeto compartilhado (.so). Esses são os mesmos arquivos de objeto compartilhados que você teria encontrado ao identificar bibliotecas nativas usando o APK Analyzer. Execute o seguinte comando em cada arquivo de objeto compartilhado:

    Linux ou macOS

    SDK_ROOT_LOCATION/Android/sdk/ndk/NDK_VERSION/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-objdump -p SHARED_OBJECT_FILE.so | grep LOAD
    

    Windows (PowerShell)

    SDK_ROOT_LOCATION\Android\sdk\ndk\NDK_VERSION\toolchains\llvm\prebuilt\windows-x86_64\bin\llvm-objdump.exe -p SHARED_OBJECT_FILE.so | Select-String -Pattern "LOAD"
    

    Em que SDK_ROOT_LOCATION é o caminho para o diretório em que você instalou o SDK do Android, SHARED_OBJECT_FILE é o nome do arquivo de objeto compartilhado que você está verificando e NDK_VERSION é a versão do NDK do Android que você instalou (por exemplo, 28.0.12433566). A saída vai ser semelhante à seguinte para cada arquivo verificado:

    LOAD off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**14
    LOAD off    0x0000000000042a90 vaddr 0x0000000000043a90 paddr 0x0000000000043a90 align 2**14
    LOAD off    0x0000000000046230 vaddr 0x0000000000048230 paddr 0x0000000000048230 align 2**14
    
  4. Verifique as linhas de saída para garantir que os segmentos de carga não tenham valores menores que 2**14. Se algum segmento de carga tiver valores 2**13, 2**12 ou menores, será necessário atualizar o pacote dessas bibliotecas, recompilar o app e fazer o teste novamente seguindo as etapas desta seção.

  5. Em seguida, execute a ferramenta de linha de comando zipalign no arquivo APK do app:

    Linux ou macOS

    SDK_ROOT_LOCATION/Android/sdk/build-tools/35.0.0/zipalign -v -c -P 16 4 APK_NAME.apk
    

    Windows (PowerShell)

    SDK_ROOT_LOCATION\Android\sdk\build-tools\35.0.0\zipalign.exe -v -c -P 16 4 APK_NAME.apk
    

    Em que SDK_ROOT_LOCATION é o caminho para o diretório em que você instalou o SDK do Android e APK_NAME é o nome do arquivo APK do app. A última linha da saída vai mostrar "Verificação concluída" se todas as bibliotecas compartilhadas estiverem alinhadas corretamente.

    Se a verificação falhar, algumas bibliotecas compartilhadas precisarão ser realinhavadas. Será necessário atualizar a embalagem dessas bibliotecas, recompilar o app e fazer o teste novamente seguindo as etapas desta seção.

Criar o app com suporte a dispositivos de 16 KB

Para oferecer suporte a dispositivos de 16 KB, os apps que usam código nativo precisam concluir as etapas descritas nas seções a seguir. Se você atualizar para a versão 8.5.1 ou mais recente do AGP e a versão r28 ou mais recente do NDK e usar dependências pré-criadas compatíveis com 16 KB, os apps serão compatíveis com 16 KB por padrão.

Atualizar o pacote das bibliotecas compartilhadas

Recomendamos que você faça upgrade para a versão 8.5.1 ou mais recente do AGP e use bibliotecas compartilhadas descompactadas.

AGP versão 8.5.1 ou mais recente

Dispositivos de 16 KB exigem que os apps que vêm com bibliotecas compartilhadas não compactadas sejam alinhados em um limite de 16 KB compactado. Para fazer isso, é necessário fazer upgrade para a versão 8.5.1 ou mais recente do Plug-in do Android para Gradle (AGP). Consulte a seção Assistente de upgrade do Plug-in do Android para Gradle para conferir detalhes sobre o processo de upgrade.

AGP versão 8.5 ou anterior

Se não for possível fazer upgrade do AGP para a versão 8.5.1 ou mais recente, a alternativa é mudar para o uso de bibliotecas compartilhadas compactadas. Atualize a configuração do Gradle para que ele comprima as bibliotecas compartilhadas ao empacotar o app para evitar problemas de instalação do app com bibliotecas compartilhadas não alinhadas.

Groovy

No arquivo build.gradle, adicione esta opção:

android {
  ...
  packagingOptions {
      jniLibs {
        useLegacyPackaging true
      }
  }
}

Kotlin

No arquivo build.gradle.kts, adicione esta opção:

android {
  ...
  packagingOptions {
      jniLibs {
        useLegacyPackaging = true
      }
  }
}

Compilar o app usando o alinhamento ELF de 16 KB

Dispositivos de 16 KB exigem que os segmentos ELF das bibliotecas compartilhadas sejam alinhados corretamente usando o alinhamento ELF de 16 KB para que o app seja executado.

Para compilar o app usando o alinhamento ELF de 16 KB, siga as etapas de uma das seções a seguir, dependendo da versão do Android NDK que você está usando.

Android NDK r28 e versões mais recentes

A versão r28 e mais recentes do NDK compilam 16 KB alinhados por padrão.

Android NDK r27

Para oferecer suporte à compilação de bibliotecas compartilhadas alinhadas a 16 KB com o Android NDK versão r27 e mais recentes, atualize as flags ndk-build, build.gradle, build.gradle.kts ou de vinculação da seguinte maneira:

ndk-build

No Application.mk:

APP_SUPPORT_FLEXIBLE_PAGE_SIZES := true

Groovy

No arquivo build.gradle, defina o argumento -DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON:

android {
  ...
  defaultConfig {
    ...
    // This block is different from the one you use to link Gradle
    // to your CMake or ndk-build script.
    externalNativeBuild {
      // For ndk-build, instead use the ndkBuild block.
      cmake {
        // Passes optional arguments to CMake.
        arguments "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
      }
    }
  }
}

Kotlin

No arquivo build.gradle.kts, defina o argumento -DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON:

android {
  ...
  defaultConfig {
    ...
    // This block is different from the one you use to link Gradle
    // to your CMake or ndk-build script.
    externalNativeBuild {
      // For ndk-build, instead use the ndkBuild block.
      cmake {
        // Passes optional arguments to CMake.
        arguments += listOf("-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON")
      }
    }
  }
}

Outros sistemas de build

Especifique as flags de vinculador a seguir:

-Wl,-z,max-page-size=16384

Android NDK r26 e versões anteriores

Para oferecer suporte à compilação de bibliotecas compartilhadas alinhadas a 16 KB com a versão r26 ou mais recente do Android NDK, atualize a configuração ndk-build ou cmake da seguinte maneira:

ndk-build

Atualize o Android.mk para ativar o alinhamento ELF de 16 KB:

LOCAL_LDFLAGS += "-Wl,-z,max-page-size=16384"

CMake

Atualize o CMakeLists.txt para ativar o alinhamento ELF de 16 KB:

target_link_options(${CMAKE_PROJECT_NAME} PRIVATE "-Wl,-z,max-page-size=16384")

Verificar instâncias de código que fazem referência a tamanhos de página específicos

Mesmo que o app esteja alinhado a 16 KB, ele pode encontrar erros se lugares no código presumirem que um dispositivo está usando um tamanho de página específico. Para evitar isso, siga estas etapas:

  1. Remova todas as dependências codificadas que fazem referência à constante PAGE_SIZE ou instâncias na lógica do código que presumem que o tamanho da página de um dispositivo é de 4 KB (4096).

    Use getpagesize() ou sysconf(_SC_PAGESIZE).

  2. Procure usos de mmap() e outras APIs que exigem argumentos alinhados à página e substitua por alternativas quando necessário.

Em alguns casos, se o app usar PAGE_SIZE como um valor conveniente que não esteja vinculado ao tamanho da página, ele não será interrompido quando usado no modo de 16 KB. No entanto, se esse valor for transmitido ao kernel com mmap sem MAP_FIXED, o kernel ainda usará uma página inteira, o que desperdiça parte da memória. Por esses motivos, PAGE_SIZE é indefinido quando o modo de 16 KB é ativado no NDK r27 e versões mais recentes.

Se o app usar PAGE_SIZE dessa maneira e nunca transmitir esse valor diretamente ao kernel, em vez de usar PAGE_SIZE, crie uma nova variável com um novo nome para refletir que ela é usada para outros fins e não reflete uma página de memória real.

Verificar o suporte a 16 KB nos SDKs

Muitos SDKs são compatíveis com tamanhos de página de 16 KB, principalmente se você os criou ou recebeu pré-criações recentes. No entanto, como alguns SDKs pré-criados ou versões de SDK não são compatíveis com 16 KB, verifique o site de cada provedor de SDK para determinar qual versão usar com 16 KB.

Testar o app em um ambiente de 16 KB

Depois de criar o app com suporte a dispositivos de 16 KB, teste o app em um ambiente de 16 KB para saber se ele tem algumas regressões. Para isso, siga estas etapas:

  1. Configure o SDK do Android 15.

  2. Configure um dos seguintes ambientes de teste:

  3. Inicie o dispositivo de teste e execute o comando abaixo para verificar se ele está usando um ambiente de 16 KB:

    adb shell getconf PAGE_SIZE
    

    O comando precisa retornar um valor de 16384.

  4. Execute o comando zipalign abaixo para verificar se o app está alinhado a 16 KB, em que APK_NAME é o nome do arquivo APK do app:

    zipalign -c -P 16 -v 4 APK_NAME.apk
    
  5. Teste seu app de forma abrangente, focando nas áreas que podem ser afetadas por mudanças nas instâncias de código que fazem referência a tamanhos de página específicos.

Configurar o Android Emulator com uma imagem do sistema Android 15 baseada em 16 KB

Para configurar um ambiente de 16 KB usando o emulador do Android, siga estas etapas:

  1. As imagens de sistema do emulador do Android 15 com base em 16 KB são compatíveis com o Android Studio Jellyfish | 2023.3.1 ou mais recente. No entanto, para ter a melhor experiência ao trabalhar com o Android 15 Beta, faça o download da versão de pré-lançamento mais recente do Android Studio.

    Lembre-se de que você pode manter a versão atual do Android Studio instalada, já que é possível instalar diversas versões lado a lado.

  2. No Android Studio, clique em Tools > SDK Manager.

  3. Na guia SDK Platforms, marque Show Package Details, expanda a seção Android VanillaIceCream Preview e selecione uma ou ambas as seguintes imagens do sistema do emulador, dependendo dos dispositivos virtuais que você quer criar:

    • Imagem do sistema experimental de 16 KB de tamanho de página de APIs do Google ARM 64 v8a
    • Google APIs Experimental 16k Page Size Intel x86_64 Atom System Image

    Fazer o download de imagens do sistema do emulador de 16 KB usando o SDK Manager no Android
    Studio

  4. Clique em Aplicar > OK para fazer o download das imagens do sistema selecionadas.

  5. Siga as etapas para configurar um dispositivo virtual para o Android 15 e, quando solicitado, selecione a imagem do sistema de 16 KB que você fez o download. Se ela não for recomendada automaticamente, você pode encontrar a imagem do sistema de 16 KB na guia Outras imagens.

    Encontre a imagem do emulador de 16 KB na guia "Outras imagens".

  1. No Gerenciador de dispositivos, clique nos três pontos ao lado da imagem de 16 KB e em Mostrar no disco.
  2. Nessa pasta, encontre o arquivo config.ini.
  3. Adicione a linha a seguir ao arquivo config.ini e salve as alterações:

    kernel.parameters = androidboot.page_shift=14
    
  4. Para verificar as mudanças, execute o comando a seguir, que deve retornar 16384:

    adb shell getconf PAGE_SIZE
    

Ativar o modo de 16 KB em um dispositivo usando as opções para desenvolvedores

Alterne a opção de desenvolvedor Inicializar com tamanho de página de 16 KB para inicializar um dispositivo no modo de 16 KB.

A partir do Android 15 QPR1, é possível usar a opção para desenvolvedores disponível em determinados dispositivos para inicializar o dispositivo no modo de 16 KB e realizar testes no dispositivo.

Essa opção para desenvolvedores está disponível nos seguintes dispositivos:

  • Pixel 8 e 8 Pro (com o Android 15 QPR1 ou mais recente)
  • Pixel 8a (com o Android 15 QPR1 ou mais recente)
  • Pixel 9, Pixel 9 Pro e Pixel 9 Pro XL (com o Android 15 QPR2 Beta 2 ou mais recente)