[Android] targetSdk 35 + 16KBページサイズ対応 完全ガイド ― ビルド確認からライブラリ更新まで

アプリを更新しようと Google Play にアップロードしたら、「16 KB ページサイズに対応していません」という警告やエラーが出て弾かれた……という経験はありませんか?あるいは、そろそろ targetSdk を上げないといけないと分かってはいるものの、後回しにしている方もいるかもしれません。

今は「targetSdk 35 の必須化」と「16 KB ページサイズ対応」という2つの要件が、ほぼ同じタイミングで効いてくる時期です。この記事では、そもそも自分のアプリが影響を受けるのかの見極めから、ビルド設定の確認、ライブラリの更新、テスト方法までを、コマンド付きで順番に整理していきます。

スポンサーリンク

まず2つの要件を整理する

要件1:targetSdk 35 の必須化

Google Play に提出する新規アプリとアップデートは、原則として Android 15(API レベル 35)以上をターゲットにする必要があります(Wear OS / Android TV / Automotive などは別要件)。すでに必須化されているので、targetSdk が 34 以下のままだと更新を出せません。

要件2:16 KB ページサイズ対応

こちらは 2025年11月1日以降に効いてくる要件です。Android 15 以上をターゲットとするアプリは、64bit デバイスで 16 KB のメモリページをサポートしている必要があります。従来 Android は 4 KB ページでしたが、RAM の大きいモダンな端末向けに 16 KB ページが採用されつつあり、その先取り対応というわけですね。

そもそも自分のアプリは影響を受ける?

ここが最初の分かれ道で、意外と重要です。16 KB 対応が必要かどうかは「ネイティブコード(.so ファイル)を含むか」で決まります。

  • Kotlin / Java だけで書かれたアプリ(標準の管理ライブラリのみ)→ すでにデフォルトで 16 KB 対応済み。基本的にコード変更は不要です。
  • ネイティブコードを含むアプリ(自前の C/C++、または .so を同梱するサードパーティ SDK を使用)→ 対応作業が必要です。

自分のアプリに .so が含まれているかは、Android Studio の Build > Analyze APK(または Analyze App Bundle)で APK/AAB を開き、lib フォルダを見れば分かります。ここに各アーキテクチャの .so があれば、ネイティブコードを含んでいるということです。カメラ系・画像処理・動画・ゲームエンジン・一部の暗号ライブラリなどは、気づかないうちに .so を引き込んでいることが多いので油断できません。

ステップ1:targetSdk 35 に上げる

まずはターゲットを上げます。build.gradle.kts(モジュールレベル)を編集します。

android {
    compileSdk = 35
 
    defaultConfig {
        // ...
        targetSdk = 35
        // minSdk はアプリの対応方針に合わせる
    }
}

targetSdk を上げると、いくつかの挙動変更(behavior changes)が適用されます。代表的なのが、API 35 以上をターゲットにするとステータスバー・ナビゲーションバーの背後までコンテンツが描画される Edge-to-Edge のデフォルト適用です。これはこれで対応が必要なので、レイアウトが被って崩れていないか必ず確認してください(Edge-to-Edge の実装は別記事で詳しく扱っています)。

ステップ2:16 KB のアライメントを確認する

ネイティブコードを含む場合、.so が 16 KB 境界にアライメントされているかを確認します。いくつか方法があります。

方法A:zipalign で APK を検証

ビルドした APK に対して、zipalign の検証モードを使います(build-tools 35.0.0 以降)。

# -c: 検証のみ / -P 16: 16KBページ想定 / 4: 4バイト境界
$ANDROID_HOME/build-tools/35.0.0/zipalign -c -P 16 -v 4 app-release.apk

最後に「Verification successful」と出れば OK です。失敗する場合は、どこかの共有ライブラリのアライメントが足りていません。

方法B:ELF セグメントのアライメントを直接見る

個々の .so がどの境界でビルドされているかは、llvm-objdump で確認できます。AAB を展開して .so を取り出し、次を実行します。

$ANDROID_HOME/ndk/<NDK_VERSION>/toolchains/llvm/prebuilt/<OS>/bin/llvm-objdump \
  -p libsample.so | grep LOAD

出力の LOAD セグメントの align2**14(=16384 = 16 KB)になっていれば対応済みです。もし 2**12(4 KB)や、それより小さい値が混じっていたら、そのライブラリは再ビルドが必要です。

方法C:テスト端末が本当に16 KBか確認

16 KB のエミュレータ/実機でテストするときは、環境そのものが 16 KB かも確認しておくと安心です。

adb shell getconf PAGE_SIZE
# 16KB環境なら 16384 が返る

ステップ3:16 KB 対応に直す

1. ツールチェインを上げる(これが本命)

いちばん確実なのは、ビルドツールを新しくすることです。具体的には次の2つ。

  • AGP(Android Gradle Plugin)8.5.1 以上:非圧縮ネイティブライブラリを 16 KB 境界に zip-align してくれます。
  • NDK r28 以上:ネイティブライブラリがデフォルトで 16 KB アライメントでコンパイルされます。

ここで一つ落とし穴があります。AGP 8.3〜8.5 は既定で 16 KB アライメントするものの、bundletool が APK を zipalign しないため、ローカルでは動いても、Play でバンドルから生成されたときにインストールできない、という現象が起きます。中途半端なバージョンで「動いてるから大丈夫」と判断せず、素直に 8.5.1 以上へ上げるのが安全です。

2. ネイティブライブラリを非圧縮にする

16 KB のアライメントを効かせるには、.so を圧縮せず APK にパッケージする必要があります。

android {
    packaging {
        jniLibs {
            // 非圧縮でパッケージ(16KBアライメントを効かせる)
            useLegacyPackaging = false
        }
    }
}

3. NDK が古い場合はリンカフラグで対応

どうしても NDK r28 に上げられない(r27 以下)場合は、リンカに 16 KB を明示します。CMake ならこう書きます。

android {
    defaultConfig {
        externalNativeBuild {
            cmake {
                arguments += "-DCMAKE_SHARED_LINKER_FLAGS=-Wl,-z,max-page-size=16384"
            }
        }
    }
}

あわせて、ネイティブコード側で ページサイズを 4096 とハードコードしている箇所があれば要注意です。mmap() のアライメント計算などで 4096PAGE_SIZE を直書きしている場合は、実行時に sysconf(_SC_PAGESIZE) で取得する形に直します。NDK r27 以降では 16 KB モード時に PAGE_SIZE が未定義になるので、この作法が推奨されています。

4. サードパーティの .so を更新する

自分のコードが正しくても、依存 SDK が同梱する .so が 4 KB アライメントだと結局アウトです。多くの主要ライブラリはすでに 16 KB 対応版をリリースしているので、依存を最新に上げるのが第一手。もし未対応のライブラリがあれば、ベンダーに更新を依頼するか、代替を検討することになります。

どうしても AGP を上げられないときの逃げ道

暫定策として、ネイティブライブラリを圧縮パッケージに切り替えるuseLegacyPackaging = true)方法もあります。圧縮されていればアライメントは問われないためです。ただしインストール時にライブラリが展開されてディスクを余計に食うので、あくまで一時しのぎ。落ち着いたら AGP を上げて非圧縮に戻すのが本筋です。

ステップ4:16 KB 環境でテストする

ビルドが通っただけでは不十分で、実際に 16 KB ページの環境で動かして確認します。Android Studio の SDK Manager から 16 KB 対応の Android 15 以上のシステムイメージを落としてエミュレータを作るのが手軽です。

実機では、一部の端末で開発者オプションから「16 KB ページサイズで起動」を切り替えてテストできます。カメラや大きなデータ処理など、ネイティブコードが絡む機能を重点的に触って、起動時クラッシュや異常が出ないかを確認しましょう。

まとめ:対応チェックリスト

  • targetSdk / compileSdk を 35 にした(Edge-to-Edge の崩れも確認)
  • APK Analyzer で .so の有無を確認した(無ければ基本OK)
  • AGP 8.5.1 以上 / NDK r28 以上に上げた
  • useLegacyPackaging = false で非圧縮パッケージにした
  • ネイティブコードの 4096 / PAGE_SIZE 直書きを排除した
  • サードパーティ .so をすべて 16 KB 対応版に更新した
  • zipalign -c -P 16llvm-objdump2**14)で確認した
  • 16 KB エミュレータ/実機で主要フローをテストした

純粋な Kotlin / Java アプリなら拍子抜けするほど簡単に済みますが、ネイティブ依存があると「自分のコードは無罪なのにサードパーティ .so で詰む」パターンが本当に多いです。締め切りに追われて慌てないよう、早めに .so の棚卸しから始めておくと安心だと思います。この記事が、あなたのリリース作業をちょっとでもスムーズにできればうれしいです。

コメント

タイトルとURLをコピーしました