16 KB ページサイズのサポート

Android 过去仅支持 4 KB 内存页面大小, 优化了系统内存性能,以针对 Android 设备通常具备的功能。从 Android 15 开始,AOSP 支持 配置为使用 16 KB (16 KB) 页面大小的设备 设备)。如果您的应用使用任何 NDK 库,请直接使用 或者通过 SDK 间接创建,那么,您需要重新构建自己的应用 支持这些 16KB 设备。

随着设备制造商不断打造出 物理内存 (RAM),许多此类设备都会采用 16KB(以及 页面大小以优化设备的性能。正在添加 支持 16 KB 页面大小的设备,可使您的应用在这些设备上运行 并有助于您的应用从相关的广告效果中获益 改进。如果不重新编译,应用可能无法在 16KB 设备上运行 在未来的 Android 版本中正式推出。

为帮助您为应用添加支持,我们提供了有关如何检查 如果您的应用受到影响 重新构建您的应用(如果适用),以及如何在 Google Play 中 使用模拟器(包括 Android 15)的 16 KB 环境 系统映像)。

メリットとパフォーマンスの向上

16 KB のページサイズで構成されたデバイスでは、平均でメモリ使用量が若干増加しますが、システムとアプリの両方でさまざまなパフォーマンスが向上します。

  • システムのメモリ負荷が高いときのアプリ起動時間の短縮: 平均 3.16% 短縮、テストした一部のアプリでは大幅な改善(最大 30%)
  • アプリ起動時の消費電力の削減: 平均 4.56% 削減
  • カメラの起動が速くなる: ホット スタートが平均 4.48%、コールド スタートが平均 6.60% 高速化
  • システムの起動時間の短縮: 平均で 8%(約 950 ミリ秒)短縮

これらの改善は初期テストに基づくものであり、実際のデバイスでの結果は異なる可能性があります。テストを継続する中で、アプリの潜在的な収益増加に関する追加の分析情報を提供していきます。

アプリが影響を受けるかどうかを確認する

アプリがネイティブ コードを使用している場合は、16 KB デバイスをサポートするようにアプリを再ビルドする必要があります。アプリがネイティブ コードを使用しているかどうか不明な場合は、APK アナライザを使用してネイティブ コードが存在するかどうかを特定し、検出された共有ライブラリの ELF セグメントの配置をチェックします。

ライブラリや SDK もすべて含めて、Java プログラミング言語または Kotlin で記述されたコードだけを使用しているアプリは、すでに 16 KB デバイスをサポートしています。ただし、16 KB 環境でアプリをテストし、アプリの動作に予期しないリグレッションがないことを確認することをおすすめします。

アプリがネイティブ コードを使用しているか?

次のいずれかに該当する場合は、アプリでネイティブ コードを使用しています。

  • アプリで C/C++(ネイティブ)コードを使用している。アプリで Android NDK を使用している場合は、アプリでネイティブ コードを使用しています。
  • アプリが、それらを使用するサードパーティのネイティブ ライブラリまたは依存関係(SDK など)とリンクしている。
  • デバイス上のネイティブ ライブラリを使用するサードパーティ製アプリビルダーでビルドされたアプリ。

APK Analyzer を使用してネイティブ ライブラリを特定する

APK Analyzer は、ビルドされた APK のさまざまな要素を評価するためのツールです。アプリがネイティブ コードとライブラリのどちらを使用しているかを特定する手順は次のとおりです。

  1. Android Studio を開き、[File] > [Open] をクリックして任意のプロジェクトを選択します。
  2. メニューバーで、[Build] > [Analyze APK...] をクリックします。

    APK Analyzer を起動する Studio の [Build] メニュー オプション

  3. 分析する APK を選択します。

  4. lib フォルダ内を調べます。共有オブジェクト(.so)ファイルがある場合はここにホストされています。共有オブジェクト ファイルが存在する場合、アプリはネイティブ コードを使用しています。共有オブジェクト ファイルが存在しない場合や、lib フォルダが存在しない場合、アプリはネイティブ コードを使用していません。

    共有オブジェクト ファイルが存在することを示す APK Analyzer ビュー

共有ライブラリの ELF セグメントのアライメントを確認する

共有ライブラリの場合は、16 KB ELF アライメントを使用して、共有ライブラリの ELF セグメントが適切にアライメントされていることを確認します。Linux または macOS で開発している場合は、次のセクションで説明するように check_elf_alignment.sh スクリプトを使用できます。コマンドライン ツールを直接使用することもできます。

check_elf_alignment.sh スクリプトを使用する(Linux または macOS)

check_elf_alignment.sh スクリプトを使用して ELF セグメントの配置を確認する手順は次のとおりです。

  1. check_elf_alignment.sh スクリプトをファイルに保存します。

  2. アプリの APK ファイルでスクリプトを実行します。

    check_elf_alignment.sh APK_NAME.apk
    

    このスクリプトは、すべての arm64-v8a 共有ライブラリに対して ALIGNED または UNALIGNED を出力します。

  3. arm64-v8a または x86_64 共有ライブラリが UNALIGNED の場合は、これらのライブラリのパッケージを更新してから、アプリを再コンパイルし、このセクションの手順に沿って再テストする必要があります。

コマンドライン ツールを直接使用する

コマンドライン ツールを直接使用して ELF セグメントの配置を確認する手順は次のとおりです。

  1. Android Studio の SDK Manager または sdkmanager コマンドライン ツールを使用して、Android SDK Build-Tools バージョン 35.0.0 以降と Android NDK の両方がインストールされていることを確認します。
  2. アプリの APK ファイルを展開します。

    Linux または macOS

    unzip APK_NAME.apk -d /tmp/my_apk_out
    

    Windows(PowerShell)

    Expand-Archive -Path .\APK_NAME.apk -DestinationPath ~\tmp\my_apk_out
    
  3. APK ファイルを展開した一時ディレクトリで、lib ディレクトリの内容を確認して、共有オブジェクト(.so)ファイルがないか確認します。これは、APK Analyzer を使用してネイティブ ライブラリを特定する際に表示された共有オブジェクト ファイルと同じです。共有オブジェクト ファイルごとに次のコマンドを実行します。

    Linux または 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"
    

    ここで、SDK_ROOT_LOCATION は Android SDK をインストールしたディレクトリのパス、SHARED_OBJECT_FILE はチェックする共有オブジェクト ファイルの名前、NDK_VERSION はインストールした Android NDK のバージョン(28.0.12433566 など)です。出力は、チェックするファイルごとに次のようになります。

    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. 出力行を確認して、負荷セグメントの値が 2**14 未満でないことを確認します。読み込みセグメントが 2**132**12、またはそれより低い値の場合は、それらのライブラリのパッケージを更新してから、アプリを再コンパイルし、このセクションの手順に沿って再テストする必要があります。

  5. 次に、アプリの APK ファイルで zipalign コマンドライン ツールを実行します。

    Linux または 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
    

    ここで、SDK_ROOT_LOCATION は Android SDK をインストールしたディレクトリのパス、APK_NAME はアプリの APK ファイルの名前です。すべての共有ライブラリが正しく配置されている場合、出力の最後の行に「検証成功」と表示されます。

    検証に失敗した場合は、一部の共有ライブラリを再調整する必要があります。そのため、それらのライブラリのパッケージを更新してから、アプリを再コンパイルし、このセクションの手順に沿って再テストする必要があります。

16 KB デバイスをサポートするようにアプリをビルドする

16 KB デバイスをサポートするには、ネイティブ コードを使用するアプリで、以下のセクションで説明する手順を完了する必要があります。AGP バージョン 8.5.1 以降と NDK バージョン r28 以降にアップデートし、16 KB 互換のビルド済み依存関係を使用すると、アプリはデフォルトで 16 KB 互換になります。

共有ライブラリのパッケージを更新する

AGP バージョン 8.5.1 以降にアップグレードし、圧縮されていない共有ライブラリを使用することをおすすめします。

AGP バージョン 8.5.1 以降

16 KB デバイスでは、圧縮されていない共有ライブラリが付属するアプリを 16 KB の zip アライメント境界に配置する必要があります。これを行うには、Android Gradle プラグイン(AGP)バージョン 8.5.1 以降にアップグレードする必要があります。アップグレード プロセスについて詳しくは、Android Gradle プラグインの Upgrade Assistant をご覧ください。

AGP バージョン 8.5 以前

AGP をバージョン 8.5.1 以降にアップグレードできない場合は、圧縮共有ライブラリの使用に切り替えることもできます。調整されていない共有ライブラリによるアプリのインストールの問題を回避するため、アプリをパッケージ化するときに Gradle が共有ライブラリを圧縮するように Gradle の構成を更新します。

Groovy

build.gradle ファイルに次のオプションを追加します。

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

Kotlin

build.gradle.kts ファイルに次のオプションを追加します。

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

16 KB ELF アライメントを使用してアプリをコンパイルする

16 KB デバイスでアプリを実行するには、共有ライブラリの ELF セグメントを 16 KB ELF アライメントを使用して適切にアライメントする必要があります。

16 KB ELF アライメントを使用してアプリをコンパイルするには、使用している Android NDK のバージョンに応じて、次のいずれかのセクションの手順を完了します。

Android NDK r28 以降

NDK バージョン r28 以降では、デフォルトで 16 KB アライメントでコンパイルされます。

Android NDK r27

Android NDK バージョン r27 以降で 16 KB アライメントの共有ライブラリのコンパイルをサポートするには、ndk-buildbuild.gradlebuild.gradle.kts、またはリンカー フラグを次のように更新する必要があります。

ndk-build

Application.mk で次のように変更します。

APP_SUPPORT_FLEXIBLE_PAGE_SIZES := true

Groovy

build.gradle ファイルで、引数 -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

build.gradle.kts ファイルで、引数 -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")
      }
    }
  }
}

他のビルドシステム

次のリンカーフラグを指定します。

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

Android NDK r26 以前

Android NDK バージョン r26 以前で 16 KB アライメントの共有ライブラリのコンパイルをサポートするには、次のように ndk-build または cmake の構成を更新する必要があります。

ndk-build

16 KB ELF アライメントを有効にするように Android.mk を更新します。

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

CMake

16 KB ELF アライメントを有効にするように CMakeLists.txt を更新します。

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

特定のページサイズを参照するコード インスタンスを確認する

アプリが 16 KB アライメントであっても、コード内の特定の場所でデバイスが特定のページサイズを使用していると想定していると、アプリでエラーが発生する可能性があります。これを回避するには、次の手順を完了します。

  1. デバイスのページサイズが 4 KB(4096)であることを前提とするコードロジック内の PAGE_SIZE 定数またはインスタンスを参照するハードコードされた依存関係をすべて削除します。

    代わりに getpagesize() または sysconf(_SC_PAGESIZE) を使用してください。

  2. ページ境界に合わせた引数を必要とする mmap() などの API の使用箇所を探し、必要に応じて代替手段に置き換えます。

アプリで PAGE_SIZE を基盤となるページサイズに関連付けられていない便利な値として使用している場合、16 KB モードで使用してもアプリが破損することはありません。ただし、この値が MAP_FIXED なしで mmap でカーネルに渡されると、カーネルはページ全体を使用するため、メモリが浪費されます。そのため、NDK r27 以降で 16 KB モードが有効になっている場合、PAGE_SIZE は未定義になります。

アプリがこのように PAGE_SIZE を使用していて、この値をカーネルに直接渡すことはない場合は、PAGE_SIZE を使用する代わりに、新しい名前の新しい変数を作成して、他の目的で使用され、実際のメモリページを反映していないことを示します。

SDK で 16 KB のサポートを確認する

多くの SDK は 16 KB のページサイズに対応しています(特に、自分でビルドする場合や、最新のビルド済みファイルを入手する場合)。ただし、一部の SDK プリビルドまたは SDK バージョンは 16 KB に対応していないため、16 KB で使用するバージョンを判断するには、各 SDK プロバイダのウェブサイトを確認する必要があります。

16 KB 環境でアプリをテストする

16 KB デバイスをサポートするようにアプリをビルドしたら、16 KB 環境でアプリをテストして、アプリにリグレッションが発生していないか確認します。手順は次のとおりです。

  1. Android 15 SDK をセットアップする

  2. 次のいずれかのテスト環境を設定します。

  3. テストデバイスを起動して、次のコマンドを実行し、16 KB 環境を使用していることを確認します。

    adb shell getconf PAGE_SIZE
    

    このコマンドは 16384 の値を返します。

  4. 次の zipalign コマンドを実行して、アプリが 16 KB でアライメントされていることを確認します。ここで、APK_NAME はアプリの APK ファイルの名前です。

    zipalign -c -P 16 -v 4 APK_NAME.apk
    
  5. 特定のページサイズを参照するコード インスタンスの変更によって影響を受ける可能性がある領域に重点を置いて、アプリを徹底的にテストします。

16 KB ベースの Android 15 システム イメージを使用して Android Emulator を設定する

Android Emulator を使用して 16 KB 環境をセットアップする手順は次のとおりです。

  1. 16 KB ベースの Android 15 エミュレータ システム イメージは、Android Studio Jellyfish | 2023.3.1 以降に対応しています。ただし、16 KB デバイスを扱う場合は、Android Studio Ladybug | 2024.2.1 以降を使用してください。

    Google は常に新機能の開発に取り組んでいます。新しいバージョンや Android Studio の最新のプレビュー版が利用可能になったら、ダウンロードすることをおすすめします。

    なお、Android Studio は複数のバージョンを一緒にインストールできるので、Android Studio の既存のバージョンをインストールしたままにしておくことができます。

  2. Android Studio で [Tools] > [SDK Manager] をクリックします。

  3. [SDK Platforms] タブで [Show Package Details] をオンにして、[Android VanillaIceCream] 以降のセクションを開き、作成する仮想デバイスに応じて、次のエミュレータ システム イメージの 1 つまたは両方を選択します。

    • Google APIs 試験運用版 16 KB ページサイズ ARM 64 v8a システム イメージ
    • Google APIs 試験運用版 16 KB ページサイズ Intel x86_64 Atom システム イメージ

    Android Studio の SDK Manager を使用して 16 KB エミュレータ システム イメージをダウンロードする

  4. [適用] > [OK] をクリックして、選択したシステム イメージをダウンロードします。

  5. 手順に沿って Android 15 の仮想デバイスをセットアップし、システム イメージを選択するよう求められたら、ダウンロードした 16 KB システム イメージを選択します。自動的に推奨されない場合は、[その他のイメージ] タブで 16 KB のシステム イメージを確認できます。

    [その他の画像] タブで 16 KB のエミュレータ イメージを見つけます。

一部のエミュレータ バージョンとシステム イメージの追加手順

Android Emulator バージョン 35.1.5 ~ 35.1.20 の場合、および SDK Manager で提供されている Android 15.0 16 KB ページサイズのシステム イメージのリビジョン 4 より前の場合、x86_64 システムで 16 KB 環境をシミュレートするには、次の手順も行う必要があります。バージョン 35.1.21 以降、および Android 15.0 16 KB ページサイズのシステム イメージのリビジョン 4 以降では、これらの手順は必要ありません。

  1. デバイス マネージャーで、16 KB の画像の横にある 3 つの点をクリックし、[ディスクに表示] をクリックします。
  2. このフォルダで config.ini ファイルを探します。
  3. config.ini ファイルに次の行を追加して、変更を保存します。

    kernel.parameters = androidboot.page_shift=14
    
  4. 変更を確認するには、次のコマンドを実行します。16384 が返されます。

    adb shell getconf PAGE_SIZE
    

エミュレータを起動する

Android Emulator と仮想デバイスの設定が完了したら、ターゲット デバイスのメニューから、またはコマンドラインからエミュレータを起動します。

開発者向けオプションを使用してデバイスで 16 KB モードを有効にする

デバイスを 16 KB モードで起動するには、[16 KB ページサイズで起動する] デベロッパー オプションを切り替えます。

Android 15 QPR1 以降では、特定のデバイスで利用可能な開発者向けオプションを使用して、デバイスを 16 KB モードで起動し、デバイス上のテストを実行できます。

この開発者向けオプションは、次のデバイスで使用できます。

  • Google Pixel 8 と Google Pixel 8 Pro(Android 15 QPR1 以降)

    警告: Android 15 QPR2 ベータ版 3 の既知の問題により、Android 15 QPR2 ベータ版 3 をインストールしてデバイスを 16 KB モードで起動すると、Google Pixel 8 のデバイスでタッチスクリーンが機能しなくなります。この問題は、Google Pixel 8 Pro デバイスには影響しません。

  • Google Pixel 8a(Android 15 QPR1 以降)

    警告: Android 15 QPR2 ベータ版 3 の既知の問題により、Android 15 QPR2 ベータ版 3 をインストールしてデバイスを 16 KB モードで起動すると、Google Pixel 8a デバイスのタッチスクリーンが機能しなくなります。

  • Google Pixel 9、Google Pixel 9 Pro、Google Pixel 9 Pro XL(Android 15 QPR2 ベータ版 2 以降)