Supportare dimensioni delle pagine di 16 kB

Storicamente, Android ha supportato solo dimensioni delle pagine di memoria di 4 KB, il che ha ottimizzato le prestazioni della memoria di sistema per la quantità media di memoria totale che i dispositivi Android hanno in genere avuto. A partire da Android 15, AOSP supporta i dispositivi configurati per utilizzare una dimensione pagina di 16 KB (dispositivi da 16 KB). Se la tua app utilizza librerie NDK, direttamente o indirettamente tramite un SDK, dovrai ricompilare l'app per farla funzionare su questi dispositivi da 16 KB.

Man mano che i produttori di dispositivi continuano a creare dispositivi con quantità maggiori di memoria fisica (RAM), molti di questi dispositivi adotteranno dimensioni delle pagine di 16 KB (e alla fine maggiori) per ottimizzare le prestazioni del dispositivo. L'aggiunta del supporto per i dispositivi con dimensioni di pagina di 16 kB consente alla tua app di essere eseguita su questi dispositivi e di sfruttare i miglioramenti delle prestazioni associati. Senza ricompilazione, le app non funzioneranno sui dispositivi da 16 KB nelle versioni future di Android.

Per aiutarti ad aggiungere il supporto per la tua app, abbiamo fornito indicazioni su come verificare se la tua app è interessata, su come ricompilare l'app (se applicabile) e su come testarla in un ambiente da 16 kB utilizzando emulatori (incluse le immagini di sistema Android 15 per Android Emulator).

Requisito di compatibilità di Google Play

Per garantire che la tua app funzioni correttamente sulle versioni più recenti di Android, tutte le app destinate ad Android 15 (livello API 35) e versioni successive devono supportare le dimensioni delle pagine di memoria di 16 kB sui dispositivi a 64 bit su Google Play. A partire dal 1° febbraio 2027, se gli aggiornamenti della tua app non supportano le dimensioni delle pagine di memoria di 16 kB, non potrai rilasciarli.

Avviso di Google Play Console che indica che gli aggiornamenti delle app devono supportare dimensioni delle pagine di memoria di 16 kB entro il 1° febbraio 2027
Figura 1. Avviso di compatibilità di Google Play Console.

Vantaggi e miglioramenti delle prestazioni

I dispositivi configurati con dimensioni di pagina di 16 KB in media utilizzano un po' più di memoria, ma ottengono anche vari miglioramenti delle prestazioni sia per il sistema sia per le app:

  • Tempi di avvio delle app più ridotti quando il sistema è sotto pressione di memoria: in media il 3,16% meno, con miglioramenti più significativi (fino al 30%) per alcune app che abbiamo testato
  • Assorbimento di corrente ridotto durante l'avvio dell'app: riduzione media del 4,56%
  • Avvio più rapido della fotocamera: in media gli avvii a caldo più veloci del 4,48% e degli avvii a freddo del 6,60% più velocemente
  • Tempo di avvio del sistema migliorato: miglioramento medio dell'8% (circa 950 millisecondi)

Questi miglioramenti si basano sui nostri test iniziali e i risultati sui dispositivi effettivi potrebbero essere diversi. Forniremo ulteriori analisi dei potenziali guadagni per le app man mano che continuiamo i test.

Verificare se la tua app è interessata

Se la tua app utilizza codice nativo, devi ricompilarla con il supporto per i dispositivi da 16 kB. Se non sai con certezza se la tua app utilizza codice nativo, puoi utilizzare APK Analyzer per identificare se è presente codice nativo e poi controllare l'allineamento dei segmenti ELF per le librerie condivise che trovi. Android Studio offre anche funzionalità che ti aiutano a rilevare automaticamente i problemi di allineamento.

Se la tua app utilizza solo codice scritto nel linguaggio di programmazione Java o in Kotlin, incluse tutte le librerie o gli SDK, allora la tua app supporta già dispositivi da 16 KB. Tuttavia, ti consigliamo di testare l'app in un ambiente da 16 KB per verificare che non si verifichino regressioni impreviste nel comportamento dell'app.

La tua app utilizza codice nativo?

La tua app utilizza codice nativo se si verifica una delle seguenti condizioni:

  • La tua app utilizza codice C/C++ (nativo). Se la tua app utilizza il Android NDK, utilizza codice nativo.
  • La tua app si collega a librerie o dipendenze native di terze parti (ad esempio SDK) che le utilizzano.
  • La tua app è creata da un generatore di app di terze parti che utilizza librerie native sul dispositivo.

Identificare le librerie native utilizzando lo Strumento di analisi APK

Strumento di analisi APK è uno strumento che ti consente di valutare vari aspetti di un APK creato. Per verificare se la tua app utilizza codice nativo (indipendentemente dal fatto che sia compatibile con 16 kB):

  1. Apri Android Studio, poi fai clic su File > Open e scegli un progetto qualsiasi.
  2. Nella barra dei menu, fai clic su Build > Analyze APK...

    Opzione del menu Build di Studio per avviare lo strumento di analisi APK
  3. Scegli l'APK che vuoi analizzare.

  4. Cerca nella cartella lib, che contiene i file oggetto condivisi (.so), se presenti. Se sono presenti file oggetto condivisi, la tua app utilizza codice nativo. La colonna Alignment mostra messaggi di avviso per tutti i file che presentano problemi di allineamento. Se non sono presenti file oggetto condivisi o non è presente una cartella lib, la tua app non utilizza codice nativo.

    Visualizzazione dello Strumento di analisi APK che mostra la presenza di file oggetto condivisi

Rilevare i problemi di allineamento con i controlli automatici

Android Studio ti avvisa in modo proattivo se le librerie o gli APK precompilati non sono conformi a 16 kB. Utilizza lo strumento APK Analyzer per esaminare le librerie che devono essere aggiornate o se sono necessarie modifiche al codice.

<figure>
  <img src="/images/guide/practices/studio-align-warnings.png"
       class="no-filter" width="300"
       alt="Studio warning notifications about alignment issues in a project">
</figure>

Lint in Android Studio evidenzia anche le librerie native che non sono allineate a 16 kB.

<figure>
  <img src="/images/guide/practices/studio-align-lint.png"
       class="no-filter"
       alt="Studio linter warning about a non-aligned native library">
</figure>

Controllare l'allineamento dei segmenti ELF per le librerie condivise

Per tutte le librerie condivise, verifica che i segmenti ELF delle librerie condivise siano allineati correttamente utilizzando l'allineamento ELF a 16 kB. Se stai sviluppando su Linux o macOS, puoi utilizzare lo script check_elf_alignment.sh come descritto nella sezione seguente. Puoi anche utilizzare direttamente gli strumenti della riga di comando.

Utilizzare lo script check_elf_alignment.sh (Linux o macOS)

Segui questi passaggi per controllare l'allineamento dei segmenti ELF utilizzando lo script check_elf_alignment.sh:

  1. Salva lo script check_elf_alignment.sh in un file.

  2. Esegui lo script sul file APK della tua app:

    check_elf_alignment.sh APK_NAME.apk
    

    Lo script restituisce ALIGNED o UNALIGNED per tutte le arm64-v8a librerie condivise.

  3. Se le librerie condivise arm64-v8a o x86_64 sono UNALIGNED, dovrai aggiornare il packaging di queste librerie, quindi ricompilare l'app e ripetere il test seguendo i passaggi descritti in questa sezione.

Utilizzare direttamente gli strumenti della riga di comando

Segui questi passaggi per controllare l'allineamento dei segmenti ELF utilizzando direttamente gli strumenti della riga di comando:

  1. Assicurati che sia SDK Android Build-Tools versione 35.0.0 o successive sia Android NDK siano installati utilizzando SDK Manager in Android Studio o sdkmanager strumento a riga di comando.
  2. Estrai il file APK della tua app:

    Linux o macOS

    unzip APK_NAME.apk -d /tmp/my_apk_out
    

    Windows (PowerShell)

    Expand-Archive -Path .\APK_NAME.apk -DestinationPath ~\tmp\my_apk_out
    
  3. Nella directory temporanea in cui hai estratto il file APK, controlla i contenuti della directory lib per i file oggetto condivisi (.so). Questi sono gli stessi file oggetto condivisi che avresti visto durante l'identificazione delle librerie native utilizzando lo Strumento di analisi APK. Esegui il comando seguente su ogni file oggetto condiviso:

    Linux o 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"
    

    Dove SDK_ROOT_LOCATION è il percorso della directory in cui hai installato SDK Android, SHARED_OBJECT_FILE è il nome del file oggetto condiviso che stai controllando e NDK_VERSION è la versione di Android NDK che hai installato (ad esempio, 28.0.12433566). L'output sarà simile al seguente per ogni file che controlli:

    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. Controlla le righe di output per assicurarti che i segmenti di caricamento non abbiano valori inferiori a 2**14. Se i segmenti di caricamento sono 2**13, 2**12 o valori inferiori , dovrai aggiornare il packaging di queste librerie, quindi ricompilare l'app e ripetere il test seguendo i passaggi descritti in questa sezione.

  5. Poi, esegui lo strumento a riga di comando zipalign sul file APK della tua app:

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

    Dove SDK_ROOT_LOCATION è il percorso della directory in cui hai installato l'SDK Android e APK_NAME è il nome del file APK della tua app. L'ultima riga dell'output indicherà "Verification successful" (Verifica riuscita) se tutte le librerie condivise sono allineate correttamente.

    Se la verifica non è riuscita, alcune librerie condivise devono essere riallineate, quindi dovrai aggiornare il packaging di queste librerie, quindi ricompilare l'app e ripetere il test seguendo i passaggi descritti in questa sezione.

Controllare il flag di sicurezza RELRO

Per mitigare gli exploit di sicurezza, i linker moderni utilizzano il flag Relocation Read-Only (RELRO) per rendere le sezioni di rilocazione del file oggetto condiviso di sola lettura dopo il caricamento. La combinazione di una sezione con RELRO abilitato con una sezione senza RELRO abilitato (da un altro file oggetto) sulla stessa pagina causa l'arresto anomalo di un'app.

Esegui il comando seguente su ogni file oggetto condiviso (Linux o macOS):

SDK_ROOT_LOCATION/Android/sdk/ndk/NDK_VERSION/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-readelf -l SHARED_OBJECT_FILE.so | grep RELRO

Controlla l'output comando per assicurarti che venga stampata la stringa GNU_RELRO, che conferma che il file .so è abilitato per RELRO.

Creare l'app con il supporto per i dispositivi a 16 kB

Se la tua app utilizza codice nativo, completa i passaggi descritti nelle sezioni seguenti per assicurarti che supporti i dispositivi a 16 kB:

  1. Aggiornare il packaging delle librerie condivise
  2. Compilare l'app utilizzando l'allineamento ELF a 16 kB
  3. Correggere il codice e risolvere i problemi di runtime
  4. Controllare gli SDK per il supporto a 16 kB

Aggiornare il packaging delle librerie condivise

Esegui l'upgrade ad AGP versione 8.5.1 o successive e utilizza librerie condivise non compresse.

Utilizzare bundletool per verificare l'allineamento ZIP

Per visualizzare l'allineamento del bundle, utilizza:

bundletool dump config --bundle=<my .aab>  | grep alignment

Se vedi PAGE_ALIGNMENT_16K, significa che il bundle richiede l'allineamento ZIP a 16 kB. Se vedi PAGE_ALIGNMENT_4K, significa che l'APK creato da questo AAB deve avere file .so allineati a 4 kB nel file ZIP.

AGP versione 8.5.1 o successive

I dispositivi a 16 kB richiedono che le app fornite con librerie condivise non compresse le allineino a un limite allineato a 16 kB. Per farlo, devi eseguire l'upgrade al plug-in Android per Gradle (AGP) versione 8.5.1 o successive. Per informazioni dettagliate sulla procedura di upgrade, consulta la sezione Android Assistente per l'upgrade del plug-in Gradle.

AGP versione 8.5 o precedenti

Se non puoi eseguire l'upgrade di AGP alla versione 8.5.1 o successive, l'alternativa è passare all'utilizzo di librerie condivise compresse. Aggiorna la configurazione di Gradle in modo che Gradle comprima le librerie condivise durante il packaging dell'app per evitare problemi di installazione dell'app con librerie condivise non allineate.

Alla moda

Nel file build.gradle, aggiungi la seguente opzione:

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

Kotlin

Nel file build.gradle.kts, aggiungi la seguente opzione:

android {
  ...
  packagingOptions {
      jniLibs {
        useLegacyPackaging = true
      }
  }
}
AGP versione 8.0 o precedenti

Se utilizzi una versione di AGP uguale o inferiore a 8.0, devi anche disattivare l'opzione della libreria nativa non compressa per gli app bundle nel file gradle.properties:

android.bundle.enableUncompressedNativeLibs=false

Compilare l'app utilizzando l'allineamento ELF a 16 kB

Per l'esecuzione dell'app, i dispositivi a 16 kB richiedono che i segmenti ELF delle librerie condivise siano allineati correttamente utilizzando l'allineamento ELF a 16 kB.

Per gli sviluppatori di giochi, se il gioco viene eseguito sul motore grafico Unity, consulta la guida di Unity. Se il gioco viene eseguito sul motore grafico Unreal, consulta la guida di Unreal. Per i motori di gioco nativi, continua con questa guida.

Per compilare l'app utilizzando l'allineamento ELF a 16 kB, completa i passaggi in una delle sezioni seguenti a seconda della versione di Android NDK che stai utilizzando.

Android NDK r28 e versioni successive

NDK versione r28 e successive vengono compilate con allineamento a 16 kB per impostazione predefinita.

Android NDK r27 e versioni precedenti

Per supportare la compilazione di librerie condivise allineate a 16 kB con Android NDK versione r27 o precedenti, utilizza i seguenti flag del linker:

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

Ecco come aggiornare i file di configurazione del sistema di compilazione:

ndk-build

Se utilizzi ndk-build, aggiorna Android.mk per attivare l'allineamento ELF a 16 kB:

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

CMake

Se utilizzi CMake, aggiorna CMakeLists.txt per attivare l'allineamento ELF a 16 kB:

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

Correggere il codice e risolvere i problemi di runtime

Anche se la tua app è allineata a 16 kB, può riscontrare errori se in alcune parti del codice si presuppone che un dispositivo utilizzi una dimensione di pagina specifica. Per evitare questo problema, completa i seguenti passaggi:

  1. Rimuovi tutte le dipendenze hardcoded che fanno riferimento alla PAGE_SIZE costante o alle istanze nella logica del codice che presuppongono che la dimensione della pagina di un dispositivo sia 4 kB (4096).

    Utilizza invece getpagesize() o sysconf(_SC_PAGESIZE).

  2. Cerca gli utilizzi di mmap() e di altre API che richiedono argomenti allineati alla pagina e sostituiscili con alternative, se necessario.

In alcuni casi, se la tua app utilizza PAGE_SIZE come valore pratico non collegato alla dimensione della pagina sottostante, non si interromperà quando viene utilizzata in modalità a 16 kB. Tuttavia, se questo valore viene passato al kernel con mmap senza MAP_FIXED, il kernel utilizza comunque un'intera pagina, il che spreca un po' di memoria. Per questi motivi, PAGE_SIZE non è definito quando la modalità a 16 kB è attivata su NDK r27 e versioni successive.

Se la tua app utilizza PAGE_SIZE in questo modo e non passa mai direttamente questo valore al kernel, PAGE_SIZEcrea una nuova variabile con un nuovo nome per indicare che viene utilizzata per altri scopi e non riflette una pagina di memoria reale.

Controllare gli SDK per il supporto a 16 kB

Molti SDK sono compatibili con le dimensioni delle pagine di 16 kB, soprattutto se li crei tu o se utilizzi versioni precompilate recenti. Tuttavia, poiché alcune versioni precompilate o versioni di SDK non sono compatibili con 16 kB, devi controllare il sito web di ogni fornitore di SDK per determinare quale versione utilizzare con 16 kB.

Testare l'app in un ambiente a 16 kB

Dopo aver creato l'app con il supporto per i dispositivi a 16 kB, dovrai testarla in un ambiente a 16 kB per verificare se si verificano regressioni. A questo scopo, procedi nel seguente modo:

  1. Configura Android 15 SDK o versioni successive.

  2. Configura uno dei seguenti ambienti di test:

  3. Avvia il dispositivo di test, quindi esegui il comando seguente per verificare che utilizzi un ambiente a 16 kB:

    adb shell getconf PAGE_SIZE
    

    Il comando deve restituire un valore di 16384.

  4. Esegui il seguente zipalign comando per verificare che l'app sia allineata a 16 kB, dove APK_NAME è il nome del file APK dell'app:

    zipalign -c -P 16 -v 4 APK_NAME.apk
    
  5. Testa attentamente l'app, concentrandoti su tutte le aree che potrebbero essere interessate da modificando le istanze di codice che fanno riferimento a dimensioni di pagina specifiche.

Configurare l'emulatore Android con un'immagine di sistema basata su 16 kB

Per configurare un ambiente a 16 kB utilizzando l'emulatore Android, segui questi passaggi:

  1. In Android Studio, fai clic su Tools > SDK Manager.
  2. Nella scheda SDK Platforms, seleziona Show Package Details, poi espandi la sezione Android VanillaIceCream o versioni successive e seleziona una o entrambe le seguenti immagini di sistema dell'emulatore, a seconda dei dispositivi virtuali che vuoi creare:

    • API di Google sperimentali 16 kB Page Size ARM 64 v8a Immagine di sistema
    • API di Google sperimentale 16 kB Page Size Intel x86_64 Atom immagine di sistema
    Scarica immagini di sistema dell'emulatore da 16 KB utilizzando SDK Manager in Android Studio
  3. Fai clic su Apply > OK per scaricare le immagini di sistema selezionate.

  4. Segui i passaggi per configurare un dispositivo virtuale per Android 15 e, quando ti viene chiesto di selezionare un'immagine di sistema, seleziona l'immagine di sistema a 16 kB che hai scaricato. Se non è consigliata automaticamente, puoi trovare l'immagine di sistema a 16 kB nella scheda Other Images (Altre immagini).

    Trova l'immagine dell'emulatore da 16 KB nella scheda Altre immagini

Avviare l'emulatore

Dopo aver completato la configurazione dell'emulatore Android e dei dispositivi virtuali, avvia l' emulatore dal menu del dispositivo di destinazione o dalla riga di comando.

Attivare la modalità a 16 kB su un dispositivo utilizzando le opzioni sviluppatore

Attiva l'opzione per sviluppatori Avvia con dimensione pagina 16 kB per avviare un dispositivo in modalità a 16 kB.

Nelle versioni QPR di Android 15, puoi utilizzare l'opzione sviluppatore disponibile su alcuni dispositivi per avviare il dispositivo in modalità 16 KB ed eseguire test sul dispositivo. Prima di utilizzare l'opzione sviluppatore, vai a Impostazioni > Sistema > Aggiornamenti software e applica gli aggiornamenti disponibili.

Questa opzione per sviluppatori è disponibile sui seguenti dispositivi:

  • Pixel 8 e 8 Pro (con Android 15 QPR1 o versioni successive)

  • Pixel 8a (con Android 15 QPR1 o versioni successive)

  • Pixel 9, 9 Pro e 9 Pro XL (con Android 15 QPR2 o versioni successive)

  • Pixel 9a (con Android 16 o versioni successive)

Modalità di compatibilità con le versioni precedenti a 16 kB

Avviso nella modalità di compatibilità con le dimensioni pagina

Avviso in modalità di compatibilità con le dimensioni pagina

L'opzione di compatibilità con le versioni precedenti a 16 kB è disponibile quando un dispositivo è in esecuzione con un kernel a 16 kB. Il gestore di pacchetti esegue un'app in modalità di compatibilità con le versioni precedenti a 16 kB quando si verificano le seguenti condizioni:

  • Se l'app ha file ELF (con estensione .so) con un allineamento del segmento LOAD di 4 kB.
  • Se l'APK compresso ha file ELF non compressi allineati a 4 kB.

Se il gestore di pacchetti ha attivato la modalità di compatibilità con le versioni precedenti a 16 kB per un'app, l'app mostra un avviso al primo avvio che indica che è in esecuzione in modalità di compatibilità con le versioni precedenti a 16 kB.

La modalità di compatibilità con le versioni precedenti a 16 kB consente il funzionamento di alcune app, ma per una maggiore affidabilità e stabilità, le app devono comunque essere allineate a 16 kB.

Nella pagina delle informazioni sull'app, in Advanced (Avanzate), attiva o disattiva l'impostazione Run app with page size compat mode (Esegui l'app in modalità di compatibilità con le dimensioni pagina) per attivare o disattivare la modalità di compatibilità con le versioni precedenti a 16 kB per un'app specifica. Questa impostazione è visibile solo quando il dispositivo è in esecuzione con dimensioni pagina di 16 kB.

Impostazione della modalità di compatibilità con le dimensioni pagina

Impostazione della modalità di compatibilità con le dimensioni pagina

Per forzare la compatibilità con le versioni precedenti a 16 kB per ogni app sul dispositivo:

adb shell setprop bionic.linker.16kb.app_compat.enabled true
adb shell setprop pm.16kb.app_compat.disabled false

Per disattivare la compatibilità con le versioni precedenti a 16 kB per ogni app sul dispositivo:

adb shell setprop bionic.linker.16kb.app_compat.enabled false
adb shell setprop pm.16kb.app_compat.disabled true

In Android 17, puoi anche disattivare la compatibilità con le versioni precedenti a 16 kB per ogni app e fare in modo che qualsiasi file binario incompatibile venga interrotto immediatamente:

    adb shell setprop bionic.linker.16kb.app_compat.enabled fatal
    adb shell setprop pm.16kb.app_compat.disabled true

Imposta la proprietà android:pageSizeCompat su enabled o disabled per attivare o disattivare la modalità di compatibilità con le versioni precedenti per un'app specifica nel relativo file AndroidManifest.xml. Quando questa proprietà è impostata, l'app non mostra avvisi relativi alla modalità di compatibilità con le versioni precedenti all'avvio.