Android 15への移行を理解して成功させる:4KBから16KBへの変更がFlutterアプリのGoogle Play公開を妨げる

Android 15への移行を理解して成功させる:4KBから16KBへの変更がFlutterアプリのGoogle Play公開を妨げる

Android 15 (API 35) 以降、Google は静かだが大規模な変更を課しています:特定のアーキテクチャでメモリページサイズが4 KBから16 KBに変わります。 低レベルの細部ですが…最終的には多くのアプリが Google Play での公開を妨げられる可能性があります。

1. Android 15で変わること

歴史的に、ほとんどの Android デバイスは4 KB のメモリページを使用していました。 Android 15 は公式に ARM v9 プロセッサと一部の x86_64 変種で16 KB のページをサポートします。

なぜこの変更か ?

  • パフォーマンス : ページフォルトの減少、大規模ワークロードでのメモリ管理の改善。
  • セキュリティ : 一部の保護機構のためにより厳密なメモリアラインメント。
  • 将来のハードウェア : 新しい SoC がこの粒度を要求します。

あなたのアプリへの影響

ネイティブバイナリ(APK/AAB 内の .so ファイル)は 16 KB にアライン され、新しい NDK (r27+) でコンパイルされている必要があります。 アプリにネイティブコードがなくても、依存関係(特にプラグイン)を通じてネイティブライブラリを含むことがあります。

2. 発生するエラーと症状

以下は、アップデート時に Flutter 開発者が典型的に遭遇する問題です :

ビルドエラー

  • checkReleaseAarMetadata : compileSdk 34+ を要求する AndroidX 依存関係
  • NDK not configured properly または unsupported page size
  • Android 14 ではビルドが成功するが、提出時に Google Play によって拒否される

ランタイムエラー

  • Android 15 の起動時にクラッシュ: libflutter.so is not aligned for 16KB page size

よくある原因

  1. compileSdk 33 に固定された Flutter プラグイン 例:awesome_notifications_corefirebase_messaging 等 → これらは Android 34+ に対してコンパイルされていない

  2. 古いツールバージョン

    • Gradle < 8.6
    • Android Gradle Plugin < 8.4
    • JDK < 17 これらのバージョンは新しい NDK/ABI のルールを認識しません。
  3. SDK プロパティの正しい伝播がされていない

    Flutter はプラグインに自動的に compileSdkVersion を強制しません。 各 Gradle サブモジュールが自身の値を定義できます。

結果:アプリは Android 35 をターゲットにしているが、あるプラグインが 33 のままコンパイルされる → ビルドが失敗。

4. 更新すべき基本事項

推奨される最小バージョン

ツール最小バージョン
Flutter SDK3.24.3
Gradle wrapper8.7
Android Gradle Plugin (AGP)8.6.1
Kotlin1.9.24
JDK17
NDKr27+

5. Android 15 対応の一般的な設定

android/gradle.properties

android.useAndroidX=true
android.enableJetifier=true

flutter.minSdkVersion=23
flutter.targetSdkVersion=35
flutter.compileSdkVersion=36

org.gradle.jvmargs=-Xmx4g -Dfile.encoding=UTF-8

android/app/build.gradle.kts

import java.util.Properties
import java.io.FileInputStream

plugins {
    id("com.android.application")
    kotlin("android")
    id("com.google.gms.google-services")
    id("com.google.firebase.crashlytics")
    id("dev.flutter.flutter-gradle-plugin")
}

val keystoreProperties = Properties()
val keystorePropertiesFile = rootProject.file("key.properties")
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}

val minSdk = providers.gradleProperty("flutter.minSdkVersion").orNull?.toInt() ?: 23
val targetSdk = providers.gradleProperty("flutter.targetSdkVersion").orNull?.toInt() ?: 35
val compileSdk = providers.gradleProperty("flutter.compileSdkVersion").orNull?.toInt() ?: 36

android {
    namespace = "com.yourcompany.yourapp"
    compileSdk = compileSdk
    ndkVersion = "29.0.13846066"

    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
    kotlinOptions { jvmTarget = "17" }

    defaultConfig {
        applicationId = "com.yourcompany.yourapp"
        minSdk = minSdk
        targetSdk = targetSdk
        versionCode = flutter.versionCode
        versionName = flutter.versionName

        ndk {
            abiFilters += listOf("arm64-v8a", "x86_64") // 64 bits only = compatible 16KB
        }
    }

    packaging {
        jniLibs.useLegacyPackaging = false
    }

    bundle {
        language.enableSplit = false
        density.enableSplit = false
        abi.enableSplit = true
    }
}

flutter {
    source = "../.."
}

そして特に : マジックブロック

問題:アプリ側で compileSdkVersion を設定しても、各 Flutter プラグインが自分の build.gradle で独自の compileSdkVersion を定義している可能性があります。1 つのプラグインが 33 のままだとビルド全体を妨げます。

解決策 : android/build.gradle.kts に、全サブプロジェクト(プラグイン)に同じバージョンを強制する以下のブロックを追加します :

Dans android/build.gradle.kts :

subprojects {
    afterEvaluate {
        val ext = extensions.findByName("android") ?: return@afterEvaluate
        val cs = providers.gradleProperty("flutter.compileSdkVersion").orNull?.toInt()
        val ts = providers.gradleProperty("flutter.targetSdkVersion").orNull?.toInt()

        @Suppress("UNCHECKED_CAST")
        (ext as? com.android.build.gradle.BaseExtension)?.apply {
            if (cs != null) setCompileSdkVersion(cs)
            defaultConfig {
                if (ts != null) targetSdkVersion(ts)
            }
        }
    }
}

なぜ afterEvaluate なのか? プラグインは Android の拡張を異なるタイミングで設定します。すべてのプラグインが設定を終えるのを待ってから変更する必要があるためです。

このブロックは、すべてのプラグインがアプリと同じ compileSdk/targetSdk を使用することを保証し、バージョンの衝突を避けます。

6. クリーンして再コンパイル

flutter clean
rm -rf android/.gradle ~/.gradle/caches
flutter pub upgrade
flutter build apk -v

7. 最終確認事項

✅ ビルドがエラーなく通る
✅ APK/AAB が arm64-v8ax86_64 の ABI を含んでいる
✅ ターゲットが targetSdkVersion 35+ である
✅ ネイティブバイナリが正しくアラインされている(16 KB 対応)

8. まとめ : Android 15 の新しいパラダイム

項目以前(Android 14)現在(Android 15)
メモリページサイズ4 KB16 KB
最小 ABIsarmeabi-v7a, arm64-v8aarm64-v8a, x86_64
NDKr25+r27+
JDK1117
AGP8.18.6
compileSdk3335/36

結論

メモリページを 16 KB に移行することは、Android エコシステムの深いモダナイゼーションを意味し、Flutter はこれに注意深く追随する必要があります。

ビルドエラー、壊れたプラグイン、Google Play の拒否といった目に見える症状は、実際には整合性を取るための信号です: パイプライン全体(Gradle、AGP、NDK、プラグイン)が一貫してバージョンアップする必要があります。

👉 もしあなたの Flutter プロジェクトが既に最新であれば、これらの手順は Android 15 への互換性を保証し、ARM v9 ハードウェアに起因する将来のクラッシュを回避します。

最後のヒント:すぐに対応する時間がない場合は、Google Play に更新猶予を申請できることがありますが、保証はありません。早めに対処するのが望ましいです!

参考資料

タグ

  • フラッター

  • ios

  • アンドロイド

  • アンドロイド 15

  • グーグルプレイ

  • グレードル

  • コトリン

  • ndk

この記事は

コメント

読み込み中...

Android 15への移行を理解して成功させる:4KBから16KBへの変更がFlutterアプリのGoogle Play公開を妨げる | DEMILY Clément