これまで Android は 4 KB のメモリ ページサイズのみをサポートしており、Android デバイスが通常備えている合計メモリの平均量に合わせてシステム メモリのパフォーマンスを最適化してきました。Android 15 以降、AOSP は 16 KB のページサイズを使用するように構成されたデバイス(16 KB デバイス)をサポートしています。アプリが NDK ライブラリを直接的または SDK を介して間接的に使用している場合は、16 KB デバイスで動作するようにアプリを再ビルドする必要があります。
デバイス メーカーが物理メモリ(RAM)の容量が大きいデバイスを構築し続けるにつれて、これらのデバイスの多くは、デバイスのパフォーマンスを最適化するために 16 KB(最終的にはそれ以上)のページサイズを採用するようになります。16 KB ページサイズのデバイスのサポートを追加すると、アプリをこれらのデバイスで実行できるようになり、関連するパフォーマンスの改善のメリットをアプリで享受できるようになります。再コンパイルしないと、今後の Android リリースで 16 KB デバイスでアプリが動作しなくなります。
アプリのサポートを追加するにあたって、アプリが影響を受けるかどうかを確認する方法、アプリを再ビルドする方法(該当する場合)、エミュレータ(Android Emulator の Android 15 システム イメージを含む)を使用して 16 KB 環境でアプリをテストする方法に関するガイダンスをご用意しました。
Google Play の互換性要件
Android の最新バージョンでアプリが正しく動作するように、Android 15(API レベル 35)以降を対象とするすべてのアプリは、Google Play の 64 ビット デバイスで 16 KB メモリのページサイズをサポートする必要があります。2027 年 2 月 1 日以降、アプリ アップデートが 16 KB メモリのページサイズをサポートしていない場合、これらのアップデートをリリースできなくなります。
メリットとパフォーマンスの向上
16 KB のページサイズで構成されたデバイスでは、平均でメモリ使用量が若干増加しますが、システムとアプリの両方でさまざまなパフォーマンスが向上します。
- システムのメモリ負荷が高いときのアプリ起動時間の短縮: 平均 3.16% 短縮、テストした一部のアプリでは大幅な改善(最大 30%)
- アプリ起動時の消費電力の削減: 平均 4.56% 削減
- カメラの起動が速くなる: ホット スタートが平均 4.48%、コールド スタートが平均 6.60% 高速化
- システムの起動時間の短縮: 平均で 8%(約 950 ミリ秒)短縮
これらの改善は初期テストに基づくものであり、実際のデバイスでの結果は異なる可能性があります。テストを継続する中で、アプリの潜在的な収益増加に関する追加の分析情報を提供していきます。
アプリが影響を受けるかどうかを確認する
アプリがネイティブ コードを使用している場合は、16 KB デバイスをサポートするようにアプリを再ビルドする必要があります。アプリがネイティブ コードを使用しているかどうか不明な場合は、APK Analyzer を使用してネイティブ コードが存在するかどうかを特定し、見つかった共有ライブラリの ELF セグメントのアライメントを確認できます。Android Studio には、配置の問題を自動的に検出するのに役立つ機能も用意されています。
ライブラリや SDK もすべて含めて、Java プログラミング言語または Kotlin で記述されたコードだけを使用しているアプリは、すでに 16 KB デバイスをサポートしています。ただし、アプリの動作に予期しない回帰がないことを確認するため、16 KB の環境でアプリをテストすることをおすすめします。
アプリがネイティブ コードを使用しているか?
該当するのは次のようなアプリです。
- アプリで C/C++(ネイティブ)コードを使用している。アプリで Android NDK を使用している場合、アプリはネイティブ コードを使用しています。
- アプリが、サードパーティのネイティブ ライブラリまたはそれらを使用する依存関係(SDK など)とリンクしている。
- アプリが、デバイス上のネイティブ ライブラリを使用するサードパーティ製アプリビルダーでビルドされている。
APK Analyzer を使用してネイティブ ライブラリを特定する
APK Analyzer は、ビルドされた APK のさまざまな要素を評価するためのツールです。アプリがネイティブ コードを使用しているかどうかを確認するには(16 KB 互換かどうかに関係なく):
- Android Studio を開き、[File] > [Open] をクリックして、任意のプロジェクトを選択します。
メニューバーから [Build] > [Analyze APK...] をクリックします。
分析する APK を選択します。
libフォルダ内を調べます。共有オブジェクト(.so)ファイルがある場合はここにホストされています。共有オブジェクト ファイルが存在する場合、アプリはネイティブ コードを使用しています。[Alignment] 列には、アライメントの問題があるファイルに関する警告メッセージが表示されます。共有オブジェクト ファイルが存在しない場合、またはlibフォルダがない場合、アプリはネイティブ コードを使用していません。
自動チェックでアライメントの問題を検出する
ビルド済みのライブラリまたは APK が 16 KB に準拠していない場合、Android Studio は事前に警告を表示します。APK Analyzer ツールを使用して、更新が必要なライブラリや、コードの変更が必要かどうかを確認します。
Android Studio の Lint でも、16 KB にアライメントされていないネイティブ ライブラリがハイライト表示されます。
共有ライブラリの ELF セグメントのアライメントを確認する
共有ライブラリについては、16 KB ELF アライメントを使用して、共有ライブラリの ELF セグメントが適切にアライメントされていることを確認します。Linux または macOS で開発している場合は、次のセクションで説明するように check_elf_alignment.sh スクリプトを使用できます。コマンドライン ツールを直接使用することもできます。
check_elf_alignment.sh スクリプトを使用する(Linux または macOS)
check_elf_alignment.sh スクリプトを使用して ELF セグメントのアライメントを確認する手順は次のとおりです。
check_elf_alignment.shスクリプトをファイルに保存します。アプリの APK ファイルに対してスクリプトを実行します。
check_elf_alignment.sh APK_NAME.apkこのスクリプトは、すべての
arm64-v8a共有ライブラリに対してALIGNEDまたはUNALIGNEDを出力します。arm64-v8aまたはx86_64共有ライブラリがUNALIGNEDの場合は、それらのライブラリのパッケージを更新してから、このセクションの手順に沿ってアプリを再コンパイルし、再テストする必要があります。
コマンドライン ツールを直接使用する
コマンドライン ツールを直接使用して ELF セグメントのアライメントを確認する手順は次のとおりです。
- Android Studio の SDK Manager または
sdkmanagerコマンドライン ツールを使用して、Android SDK Build-Tools バージョン 35.0.0 以降と Android NDK の両方がインストールされていることを確認します。 アプリの APK ファイルを抽出します。
Linux または macOS
unzip APK_NAME.apk -d /tmp/my_apk_outWindows(PowerShell)
Expand-Archive -Path .\APK_NAME.apk -DestinationPath ~\tmp\my_apk_outAPK ファイルを抽出した一時ディレクトリで、
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 LOADWindows(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出力行をチェックして、負荷セグメントの値が
2**14未満でないことを確認します。読み込みセグメントが2**13、2**12、またはそれ以下の値の場合は、それらのライブラリのパッケージを更新してから、アプリを再コンパイルし、このセクションの手順に沿って再テストする必要があります。次に、アプリの APK ファイルに対して
zipalignコマンドライン ツールを実行します。Linux または macOS
SDK_ROOT_LOCATION/Android/sdk/build-tools/35.0.0/zipalign -v -c -P 16 4 APK_NAME.apkWindows(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 ファイルの名前です。すべての共有ライブラリが正しく調整されている場合、出力の最後の行に「Verification successful」と表示されます。検証に失敗した場合は、一部の共有ライブラリを再調整する必要があります。そのため、それらのライブラリのパッケージを更新してから、アプリを再コンパイルし、このセクションの手順に沿って再テストする必要があります。
RELRO セキュリティ フラグを確認する
セキュリティの脆弱性を軽減するため、最新のリンカーは、Relocation Read-Only(RELRO)フラグを使用して、読み込み後に共有オブジェクト ファイルの再配置セクションを読み取り専用にします。ビルドで RELRO フラグを有効にします。
RELRO セクションの開始アドレスとセグメント サイズ(MemSize)の合計が 16 KB にアライメントされていない場合、アプリは実行時にセグメンテーション違反でクラッシュします。これは、関連するフラグを有効にせずに、NDK ツールチェーン r27 以前で .so ファイルがビルドされた場合に発生します。
共有オブジェクト ファイルごとに次のコマンドを実行します(Linux または macOS)。
SDK_ROOT_LOCATION/Android/sdk/ndk/NDK_VERSION/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-readelf -Wl SHARED_OBJECT_FILE.so | grep 'RELRO\|Type'
RELRO セグメントがある場合は、GNU_RELRO 文字列が出力されます。
次に、仮想オフセット アドレス(VirtAddr)とセグメント メモリサイズ(MemSiz)を合計し、16 KB(0x4000)で割って、RELRO セグメントのアライメントを確認します。剰余(モジュロ)がゼロの場合、RELRO セグメントは 16 KB アライメントされます。
以下に、アライメントされていない .so ファイルの例を示します。
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
GNU_RELRO 0x0cfaf0 0x00000000000dfaf0 0x00000000000dfaf0 0x01510 0x01510 R 0x1
計算式: (VirtAddr + MemSiz) % 0x4000 == 0
結果: (0xdfaf0 + 0x01510) % 0x4000 = 0xE1000 % 0x4000 == 0x1000
0x1000 はゼロではないため、この .so ファイルは 16 KB に準拠していません。DC000(前の改ページ)から E4000 までの RELRO 保護範囲は読み取り専用ですが、Android リンカーは E1000 から E4000 までのサブ範囲が書き込み可能であることを想定しているため、セグメンテーション違反が発生します。この場合は、16 KB ELF アライメントを使用してアプリをコンパイルするセクションの説明に沿って、.so ファイルを再ビルドします。
RELRO セグメントを含む、アライメントされた .so ファイルの例を次に示します。
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
GNU_RELRO 0x0cfaf0 0x00000000000dfaf0 0x00000000000dfaf0 0x01510 0x00510 R 0x1
RELRO セグメントのない .so ファイルの例を次に示します。
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
これは、RELRO セグメントのない、16 KB に準拠した単純な .so ファイルです。
GNU_RELRO が独自の LOAD セグメントにある、アライメントされた .so ファイルの例を次に示します。
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x000680 0x000680 R E 0x4000
LOAD 0x000680 0x0000000000004680 0x0000000000004680 0x0001d8 0x000980 RW 0x4000
GNU_RELRO 0x000680 0x0000000000004680 0x0000000000004680 0x0001d8 0x000980 R 0x1
計算式: (VirtAddr + MemSiz) % 0x4000 == 0
結果: (0x4680 + 0x0980) % 0x4000 = 0x5000 % 0x4000 == 0x1000
0x1000 はゼロではありませんが、この .so ファイルは 16 KB に準拠しています。
モジュロ式は、GNU_RELRO が後続の書き込み可能なデータ(.data や .bss など)と LOAD セグメントを共有する場合に適用されます。
GNU_RELRO が独自の LOAD セグメントにあるかどうかを確認するには、llvm-readelf -Wl を実行して grep 'LOAD\|RELRO\|Type' でフィルタリングし、プログラム ヘッダーを調べます。GNU_RELRO の VirtAddr と MemSiz を、それを含む LOAD セグメントと比較します。この例では、両方に VirtAddr 0x4680 と MemSiz 0x0980 があります。
LOAD セグメント全体には RELRO データのみが含まれているため、0x5000 から 0x8000 までのサブ範囲に書き込み可能なデータはありません。また、後続の書き込み可能な LOAD セグメントは、別の 16 KB ページ境界(0x8000 以降)で開始されます。リンカーの読み取り専用保護は書き込み可能なデータと重複しないため、セグメンテーション違反は発生しません。
16 KB デバイスをサポートするアプリをビルドする
アプリがネイティブ コードを使用している場合は、次のセクションで説明する手順に沿って、アプリが 16 KB デバイスをサポートしていることを確認します。
- 共有ライブラリのパッケージングを更新する
- 16 KB ELF アライメントを使用してアプリをコンパイルする
- コードを修正してランタイムの問題を解決する
- カスタム メモリ アロケータを最適化する(該当する場合)
- SDK が 16 KB をサポートしているかどうかを確認する
共有ライブラリのパッケージ化を更新する
AGP バージョン 8.5.1 以降にアップグレードして、圧縮されていない共有ライブラリを使用してください。
bundletool を使用して zip アライメントを検証する
バンドルの配置を確認するには、次のコマンドを使用します。
bundletool dump config --bundle=<my .aab> | grep alignment
PAGE_ALIGNMENT_16K が表示された場合は、バンドルが 16 KB の zip アライメントをリクエストしていることがわかります。PAGE_ALIGNMENT_4K が表示された場合、この AAB からビルドされた APK に、zip ファイル内の 4 KB の .so ファイルを配置するよう指示します。
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
}
}
}
AGP バージョン 8.0 以下
8.0 以下の AGP バージョンを使用している場合は、gradle.properties ファイルで App Bundle の非圧縮ネイティブ ライブラリ オプションを無効にする必要もあります。
android.bundle.enableUncompressedNativeLibs=false
16 KB ELF アライメントを使用してアプリをコンパイルする
16 KB デバイスでは、アプリを実行するために、共有ライブラリの ELF セグメントを 16 KB ELF アライメントを使用して適切に配置する必要があります。
ゲーム デベロッパーの場合、ゲームが Unity ゲームエンジン上で動作する場合は、Unity ガイドを参照してください。ゲームが Unreal ゲームエンジン上で実行される場合は、Unreal のガイドを参照してください。ネイティブ ゲームエンジンの場合は、このガイドを続行してください。
16 KB ELF アライメントを使用してアプリをコンパイルするには、使用している Android NDK のバージョンに応じて、次のいずれかのセクションの手順を完了します。
Android NDK r28 以降
NDK バージョン r28 以降では、デフォルトで 16 KB にアライメントされたコンパイルが行われます。
Android NDK r27 以前
Android NDK バージョン r27 以下で 16 KB アライメントの共有ライブラリのコンパイルをサポートするには、次のリンカーフラグを使用します。
-Wl,-z,max-page-size=16384
-Wl,-z,common-page-size=16384
ビルドシステムの構成ファイルを更新する方法は次のとおりです。
ndk-build
ndk-build を使用している場合は、Android.mk を更新して 16 KB ELF アライメントを有効にします。
LOCAL_LDFLAGS += -Wl,-z,max-page-size=16384 -Wl,-z,common-page-size=16384
CMake
CMake を使用している場合は、CMakeLists.txt を更新して 16 KB ELF アライメントを有効にします。
target_link_options(${CMAKE_PROJECT_NAME} PRIVATE
"-Wl,-z,max-page-size=16384"
"-Wl,-z,common-page-size=16384"
)
コードを修正してランタイムの問題を解決する
アプリが 16 KB に対応していても、コード内の特定の場所でデバイスが特定のページサイズを使用していることが前提とされている場合は、エラーが発生する可能性があります。これを回避するには、次の操作を行います。
PAGE_SIZE定数を参照するハードコードされた依存関係や、デバイスのページサイズが 4 KB(4096)であることを前提とするコードロジック内のインスタンスを削除します。代わりに
getpagesize()またはsysconf(_SC_PAGESIZE)を使用してください。mmap()や、ページに沿った引数を必要とするその他の API の使用を探し、必要に応じて代替 API に置き換えます。
アプリが、基盤となるページサイズに関連付けられていない便利な値として PAGE_SIZE を使用している場合、16 KB モードで使用してもアプリが破損することはありません。ただし、この値が MAP_FIXED なしで mmap を使用してカーネルに渡されると、カーネルはページ全体を使用するため、メモリが無駄になります。こうした理由から、NDK r27 以降で 16 KB モードが有効になっている場合、PAGE_SIZE は未定義になります。
アプリがこのように PAGE_SIZE を使用し、この値をカーネルに直接渡さない場合は、PAGE_SIZE を使用する代わりに、他の目的で使用され、実際のメモリページを反映していないことを示す新しい名前の新しい変数を作成します。
カスタム メモリ アロケータを最適化する
16 KB システムでは、オペレーティング システムが割り当てる物理メモリの最小単位が 4 KB システムの 4 倍になります。カスタム アロケータが 4 KB の前提に基づいて設計されている場合、小さなオブジェクトが複数の 16 KB ページに分散され、空のメモリが不必要に保持される可能性があります。これにより、物理メモリ使用量(RSS)が大幅に増加し、圧縮スワップ(ZRAM)の効率が低下する可能性があります。
コードが独自のメモリプールを管理している場合は、次の推奨事項に従ってください。
1. メモリを解放するためのバイトしきい値をハードコードしない
多くのアロケータは、固定バイト上限を使用して、madvise(MADV_DONTNEED) を使用してメモリを OS に解放するタイミングを決定します(たとえば、アクティブなオブジェクトが 8 KB 未満の場合にのみメモリを解放するなど)。
16 KB システムでは、1 つの 16 バイトのライブ オブジェクトでも、16 KB ページ全体(8 KB を超える)が固定されます。その結果、解放しきい値に達することはなく、アロケータは周囲の未使用メモリをカーネルに返しません。
対応策: ページリリース ヒューリスティックにハードコードされたバイト定数を使用しないでください。sysconf(_SC_PAGESIZE) を使用して、実際のページサイズに基づいて実行時にリリースしきい値を動的にスケーリングします。
2. 使用済みのページを先に埋める(密優先割り当て)
アロケータが先入れ先出し(FIFO)またはラウンドロビン順でメモリを割り当てると、新しい割り当てが部分的に埋められた 16 KB ページに分散されます。ページ上の 1 つのオブジェクトが、16 KB すべてを物理 RAM に常駐させます。
対処方法: 空のページや使用頻度の低いページにアクセスする前に、最も使用率の高い(密度の高い)ページまたはスラブから新しいオブジェクトを常に割り当てます。新しい割り当てをすでにダーティなページに集中させることで、使用頻度の低いページは自然にアクティブなオブジェクトがゼロになり、16 KB のページ全体を OS に解放できます。
3. メモリプールを 16 KB にアライメントし、プールサイズを適度に保つ
4 KB システム用に設計されたマルチページ スパンは、16 KB カーネルで過剰な未解放メモリ スラックを保持する可能性があります。また、16 KB に均等に分割されないサイズクラスは、各ページの末尾で断片化を引き起こします。
手順:
- すべてのメモリプール、スラブ境界、バッファ アライメントが、ランタイム ページサイズの正確な倍数であることを確認します。
- アイドル状態のメモリをトラップする過度に大きなスラブの割り当てを回避するため、小オブジェクト クラスのマルチページ スパン サイズを再評価。
4. キャッシュに保存された大きなバッファの物理メモリを直ちに解放
カスタム アロケータは、多くの場合、大きなバッファ(64 KB 超)をインメモリ プールにキャッシュします。これにより、mmap または munmap システムコールのオーバーヘッドを発生させることなく、バッファを再利用できます。ただし、これらのダーティ バッファをメモリに保持すると、エビクション タイマーを待機している間に、数メガバイトの物理 RAM が無駄になります。
対処方法: 仮想メモリアドレス範囲は、高速再利用のために予約したままにしますが、バッファをキャッシュに返すときに、すぐに madvise(..., MADV_DONTNEED) または madvise(..., MADV_FREE) を呼び出します。オペレーティング システムは物理 RAM をすぐに再利用しますが、アプリは再割り当てなしで仮想アドレスをすぐに再利用できます。
5. ZRAM 圧縮の割り当て時ではなく、解放時にメモリをゼロにする
Android は、圧縮スワップ(ZRAM)を使用してバックグラウンド アプリをメモリに保持します。16 KB のデバイスでは、ページに 1 つでもライブ オブジェクトが含まれている場合、16 KB のページ全体が常駐するか、ZRAM にスワップされます。そのページの以前に解放された部分に残っているゴミデータ(古いポインタや文字列など)は、圧縮率が低くなります。
アロケータがメモリをゼロにする場合(セキュリティやゼロ初期化された割り当てなど)、割り当て時ではなく、割り当て解除時(free())にゼロにすることを検討してください。
- 固定されたページのコストが低い: 部分的に埋められた 16 KB ページのアイドル状態のメモリは、ZRAM でほぼゼロに圧縮されるため、固定されたページが物理スワップ領域を浪費することはありません。
- 最小限のキャッシュ オーバーヘッド:
free()が呼び出された時点で、メモリはすでに CPU キャッシュ内でホットな状態になっているため、後で追加のキャッシュミスが発生するのを回避できます。
推奨事項の概要
| 地域 | 推奨事項 | 想定される影響 |
|---|---|---|
| パージのしきい値 | sysconf(_SC_PAGESIZE) を使用して、リリースしきい値を動的にスケーリングする。 |
リリース ロジックが永久にデッドロックするのを防ぎます。 |
| 割り当て順序 | 最も密度の高い(ほぼいっぱいの)ページまたはスラブから最初に割り当てます。 | アクティブなオブジェクトをまとめてパックすることで、常駐メモリ(RSS)を削減します。 |
| スパンのサイズ設定 | サイズクラスを 16 KB の倍数に揃え、特大のスラブを回避します。 | 末尾ページの断片化を解消し、メモリの余裕を減らします。 |
| バッファ キャッシュ | 大きなバッファをキャッシュに保存する場合は、すぐに madvise(MADV_DONTNEED) を呼び出します。 |
高速な仮想再利用を維持しながら、アイドル状態の RAM の肥大化を排除します。 |
| スワップ / ZRAM | 割り当て時ではなく、free() でメモリをゼロにします。 |
ZRAM の圧縮率が向上し、固定されたページのコストが削減されます。 |
16 KB をサポートする SDK を確認する
多くの SDK は 16 KB のページサイズに対応しています。特に、自分でビルドする場合や、最近のビルド済み SDK を入手する場合は、16 KB のページサイズに対応しています。ただし、一部の SDK プリビルドまたは SDK バージョンは 16 KB に対応していないため、各 SDK プロバイダのウェブサイトで、16 KB で使用するバージョンを確認する必要があります。
16 KB 環境でアプリをテストする
16 KB デバイスをサポートするアプリをビルドしたら、16 KB 環境でアプリをテストして、アプリにリグレッションが発生していないかどうかを確認します。手順は次のとおりです。
Android 15 SDK 以降をセットアップします。
次のいずれかのテスト環境をセットアップします。
テストデバイスを起動し、次のコマンドを実行して、16 KB 環境を使用していることを確認します。
adb shell getconf PAGE_SIZEこのコマンドは
16384の値を返します。次の
zipalignコマンドを実行して、アプリが 16 KB アラインメントされていることを確認します。ここで、APK_NAME はアプリの APK ファイルの名前です。zipalign -c -P 16 -v 4 APK_NAME.apkアプリを徹底的にテストします。特定のページサイズを参照するコード インスタンスの変更によって影響を受ける可能性のある領域に重点を置いてください。
16 KB ベースのシステム イメージを使用して Android Emulator をセットアップする
Android Emulator を使用して 16 KB 環境をセットアップする手順は次のとおりです。
- Android Studio で [Tools] > [SDK Manager] をクリックします。
[SDK Platforms] タブで [Show Package Details] を選択し、[Android VanillaIceCream] 以降のセクションを開いて、作成する仮想デバイスに応じて、次のエミュレータ システム イメージのいずれかまたは両方を選択します。
- Google APIs Experimental 16 KB Page Size ARM 64 v8a System Image
- Google APIs Experimental 16 KB Page Size Intel x86_64 Atom System Image
[Apply] > [OK] をクリックして、選択したシステム イメージをダウンロードします。
Android 15 用の仮想デバイスをセットアップする手順に沿って、システム イメージを選択するよう求められたら、ダウンロードした 16 KB のシステム イメージを選択します。自動的に推奨されない場合は、[Other Images] タブで 16 KB のシステム イメージを見つけることができます。
エミュレータを起動する
Android Emulator と仮想デバイスの設定が完了したら、対象デバイス メニューまたはコマンドラインからエミュレータを起動します。
開発者向けオプションを使用してデバイスで 16 KB モードを有効にする
[16 KB ページサイズで起動する] デベロッパー オプションを切り替えて、デバイスを 16 KB モードで起動します。
Android 15 の QPR バージョンでは、特定のデバイスで利用可能なデベロッパー オプションを使用して、デバイスを 16 KB モードで起動し、オンデバイス テストを実行できます。開発者向けオプションを使用する前に、[設定] > [システム] > [ソフトウェア アップデート] に移動して、利用可能なアップデートを適用します。
この開発者向けオプションは、次のデバイスで利用できます。
Google Pixel 8、Google Pixel 8 Pro(Android 15 QPR1 以降)
Google Pixel 8a(Android 15 QPR1 以降)
Google Pixel 9、9 Pro、9 Pro XL(Android 15 QPR2 以降搭載)
Google Pixel 9a(Android 16 以降搭載)
16 KB 後方互換モード
ページサイズ互換モードでの警告
16 KB の後方互換オプションは、デバイスが 16 KB カーネルで実行されている場合に使用できます。パッケージ マネージャーは、次の条件が満たされた場合にアプリを 16 KB の後方互換モードで実行します。
- アプリに ELF ファイル(拡張子は
.so)が含まれており、LOAD セグメントのアライメントが 4 KB の場合。 - 圧縮済みの APK に圧縮されていない ELF ファイルがあり、それが 4 KB で ZIP アライメントされている場合。
パッケージ マネージャーがアプリに対して 16 KB の後方互換モードを有効にしている場合、そのアプリを初めて起動する際に、16 KB の後方互換モードで実行されていることを示す警告が表示されます。
16 KB の後方互換モードで一部のアプリは動作しますが、信頼性と安定性を最大限に高めるには、アプリを 16 KB アライメントにする必要があります。
アプリ情報ページの [詳細設定] で、[ページサイズ互換モードでアプリを実行する] 設定を切り替え、特定のアプリに対する 16 KB の後方互換モードを有効または無効にします。この設定は、デバイスが 16 KB のページサイズで実行されている場合にのみ表示されます。
ページサイズ互換モードの設定
デバイス上のすべてのアプリで 16 KB の後方互換モードを強制的に有効にするには:
adb shell setprop bionic.linker.16kb.app_compat.enabled true
adb shell setprop pm.16kb.app_compat.disabled false
デバイス上のすべてのアプリで 16 KB の後方互換モードを強制的に無効にするには:
adb shell setprop bionic.linker.16kb.app_compat.enabled false
adb shell setprop pm.16kb.app_compat.disabled true
Android 17 では、すべてのアプリで 16 KB の後方互換モードを強制的に無効にして、互換性のないバイナリを直ちに中止することもできます。
adb shell setprop bionic.linker.16kb.app_compat.enabled fatal
adb shell setprop pm.16kb.app_compat.disabled true
android:pageSizeCompat プロパティを有効または無効に設定して、AndroidManifest.xml 内の特定のアプリの後方互換モードをオンまたはオフにします。このプロパティが設定されている場合、アプリの起動時に後方互換モードの警告は表示されません。