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

Sommaire
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
よくある原因
-
compileSdk 33に固定された Flutter プラグイン 例:awesome_notifications_core、firebase_messaging等 → これらは Android 34+ に対してコンパイルされていない -
古いツールバージョン
- Gradle < 8.6
- Android Gradle Plugin < 8.4
- JDK < 17 これらのバージョンは新しい NDK/ABI のルールを認識しません。
-
SDK プロパティの正しい伝播がされていない
Flutter はプラグインに自動的に
compileSdkVersionを強制しません。 各 Gradle サブモジュールが自身の値を定義できます。
結果:アプリは Android 35 をターゲットにしているが、あるプラグインが 33 のままコンパイルされる → ビルドが失敗。
4. 更新すべき基本事項
推奨される最小バージョン
| ツール | 最小バージョン |
|---|---|
| Flutter SDK | 3.24.3 |
| Gradle wrapper | 8.7 |
| Android Gradle Plugin (AGP) | 8.6.1 |
| Kotlin | 1.9.24 |
| JDK | 17 |
| NDK | r27+ |
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-v8a と x86_64 の ABI を含んでいる
✅ ターゲットが targetSdkVersion 35+ である
✅ ネイティブバイナリが正しくアラインされている(16 KB 対応)
8. まとめ : Android 15 の新しいパラダイム
| 項目 | 以前(Android 14) | 現在(Android 15) |
|---|---|---|
| メモリページサイズ | 4 KB | 16 KB |
| 最小 ABIs | armeabi-v7a, arm64-v8a | arm64-v8a, x86_64 |
| NDK | r25+ | r27+ |
| JDK | 11 | 17 |
| AGP | 8.1 | 8.6 |
| compileSdk | 33 | 35/36 |
結論
メモリページを 16 KB に移行することは、Android エコシステムの深いモダナイゼーションを意味し、Flutter はこれに注意深く追随する必要があります。
ビルドエラー、壊れたプラグイン、Google Play の拒否といった目に見える症状は、実際には整合性を取るための信号です: パイプライン全体(Gradle、AGP、NDK、プラグイン)が一貫してバージョンアップする必要があります。
👉 もしあなたの Flutter プロジェクトが既に最新であれば、これらの手順は Android 15 への互換性を保証し、ARM v9 ハードウェアに起因する将来のクラッシュを回避します。
最後のヒント:すぐに対応する時間がない場合は、Google Play に更新猶予を申請できることがありますが、保証はありません。早めに対処するのが望ましいです!
参考資料
コメント
読み込み中...