ANTIGRAVITY LABEN
記事一覧/アプリ開発
アプリ開発/2026-06-27上級

AI Studio が選んだ Gradle と AGP のバージョンが、既存アプリのビルドを静かに壊す前に

AI Studio が生成した Kotlin/Compose 画面を既存の Android アプリへ取り込むと、AGP・Kotlin・依存ライブラリのバージョンがずれてビルドが静かに壊れます。version catalog で単一の真実を固定し、取り込み口で生成側の宣言を検査するゲートの設計を、実測とコードでまとめました。

antigravity394ai-studio3android24gradle2jetpack-compose3

プレミアム記事

生成された画面はエミュレータで完璧に動いていました。問題は、その画面のフォルダを自分の壁紙アプリのモジュールへコピーした瞬間に起きました。./gradlew assembleRelease は通るのに、デバッグビルドだけが Unsupported class file major version で落ちる。原因にたどり着くまで半日かかりましたが、犯人は私のコードでも生成されたコードでもなく、AI Studio が同梱してきた build.gradle.kts の中で宣言された AGP と Kotlin のバージョンでした。

AI Studio が Kotlin と Jetpack Compose のアプリをテキストから生成し、エミュレータ実行から実機転送、Google Play 内部テストまで一画面でつなげられるようになって、個人開発の試作と配布の距離はずいぶん縮みました。けれど生成物は「新規アプリ」として整っているだけで、既に動いている自分のアプリに混ぜる前提では作られていません。ここに静かな落とし穴があります。

ここでは、生成された Compose を既存アプリへ取り込むときに発生するバージョンずれを、version catalog を単一の真実として固定し、取り込み口で生成側の宣言を機械的に検査するゲートで防ぐ設計をまとめます。私が個人開発で運用している Android 壁紙アプリの実運用で踏んだ失敗と、それを止めた具体的な構成を中心にまとめます。

なぜ「動いた生成コード」が既存アプリで壊れるのか

AI Studio の生成物は、その時点で最新の安定版に寄せた依存を宣言します。一方、長く運用しているアプリは、互換性を確かめながら少しずつ上げてきた固有のバージョン構成を持っています。この二つを単純にマージすると、Gradle は依存解決の途中でより新しい方へ寄せるため、あなたが意図的に止めていたバージョンが、取り込みと同時に黙って引き上げられます。

実際に私が遭遇した壊れ方を、影響範囲とともに整理します。

ずれた要素生成側が宣言しがちな値既存アプリで起きたこと
AGP(Android Gradle Plugin)最新メジャー(例: 9.x 系)Java 8 API を使う旧ライブラリで NoClassDefFoundError。desugaring の有効化が前提に
Kotlin / Compose コンパイラ最新安定Compose コンパイラと Kotlin の対応表からずれ、Compose Compiler requires Kotlin version で停止
core ライブラリ(画像・DI 等)最新API シグネチャ変更で既存画面側がコンパイルエラー
minSdk / targetSdk生成時点の推奨minSdk が上がり、サポート対象だった旧端末が配信対象から外れる

このうち AGP の引き上げは特に厄介でした。私のアプリでは画像表示ライブラリが内部で Java 8 の Supplier を参照していて、AGP のメジャー更新後に Android 6.0.1 帯の端末で起動直後にクラッシュするようになったのです。解決自体は一行で、coreLibraryDesugaringEnabled を有効化して desugaring ライブラリを足すだけでしたが、「生成コードを混ぜたらクラッシュ率が上がった」という因果が見えにくいのが本当の問題でした。この desugaring 周りの詳しい挙動は古い端末で起きる Java 8 由来のクラッシュを desugaring で止めた記録に切り分けの手順を書いています。

ここで効くのが「単一の真実(single source of truth)」という考え方です。バージョンを各モジュールの build.gradle.kts に散らさず、gradle/libs.versions.toml の version catalog 一箇所に集約しておけば、生成物が独自に宣言したバージョンは取り込みの時点で必ず catalog と突き合わせられるようになります。

version catalog を単一の真実として固定する

まず、プロジェクト全体のバージョンを version catalog に寄せます。生成物が個別に書いてくる implementation("androidx.compose...:1.x.x") のような直書きを排除し、すべて catalog 参照に統一するのが出発点です。

# gradle/libs.versions.toml — プロジェクトで唯一バージョンを宣言する場所
[versions]
agp = "9.0.1"                # ここで止める。生成物が 9.1.x を宣言しても上げない
kotlin = "2.2.20"
composeCompiler = "2.2.20"   # kotlin と一致させる(Kotlin 2.x は composeOptions 不要だが明示管理)
composeBom = "2026.05.01"
coreDesugar = "2.1.5"        # AGP メジャー更新後の Java 8 由来クラッシュ対策
minSdk = "23"                # Android 6.0。生成物が上げてきても維持する
targetSdk = "36"
 
[libraries]
compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
compose-ui = { group = "androidx.compose.ui", name = "ui" }
compose-material3 = { group = "androidx.compose.material3", name = "material3" }
desugar-jdk-libs = { group = "com.android.tools", name = "desugar_jdk_libs", version.ref = "coreDesugar" }
 
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }

次に、モジュール側ではバージョンを一切書かず、catalog の別名だけを参照します。Compose は BOM 経由で版を揃えるので、個々のライブラリにバージョンを付けないのが要点です。

// app/build.gradle.kts — バージョンは書かない。catalog の別名だけを使う
plugins {
    alias(libs.plugins.android.application)
    alias(libs.plugins.kotlin.android)
    alias(libs.plugins.kotlin.compose)
}
 
android {
    compileSdk = libs.versions.targetSdk.get().toInt()
    defaultConfig {
        minSdk = libs.versions.minSdk.get().toInt()
        targetSdk = libs.versions.targetSdk.get().toInt()
    }
    compileOptions {
        // AGP メジャー更新で古い端末が落ちないよう desugaring を常時有効化
        isCoreLibraryDesugaringEnabled = true
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }
}
 
dependencies {
    val composeBom = platform(libs.compose.bom)
    implementation(composeBom)
    implementation(libs.compose.ui)
    implementation(libs.compose.material3)
    coreLibraryDesugaring(libs.desugar.jdk.libs)  // 上の TOML と対で必ず入れる
}

これで「どのモジュールから見てもバージョンは catalog の一箇所」という状態になります。生成物をこのプロジェクトに混ぜるとき、生成側が直書きしたバージョンはそのままでは catalog 経由にならないので、取り込み口でそれを検出できます。

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
AI Studio が生成した Compose 画面を、自分の既存アプリへ取り込むときにビルドが壊れていた人が、依存の衝突を事前に止める固定方法を今日から実装できる
AGP・Kotlin・Compose コンパイラ・主要ライブラリのバージョンを version catalog で単一の真実として束ね、生成コードの宣言を取り込み口で検査するゲートを構築できる
段階公開中の本番アプリに生成画面を混ぜても、Android 6.0 帯のクラッシュや密度バケットの欠落を再発させずに配信フローへ載せられるようになる
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Antigravity Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

アプリ開発2026-04-25
Gemma 4 × Antigravity — iOS・Android 両対応オンデバイスAI 実装ガイド
Gemma 4 モデルを iOS(Core ML)と Android(TensorFlow Lite / AI Core)の両プラットフォームに本番統合する手順を、Antigravity で AI 支援しながら詳解。モデル変換・量子化・審査対策まで。
アプリ開発2026-03-29
Antigravity × Jetpack Compose で Android UI を AI アシスト開発する実践ガイド
Antigravity IDE と Jetpack Compose を組み合わせた Android UI 開発の実践手法を解説。AI によるコンポーネント生成、プレビュー活用、テーマ設計まで具体的なコード例とともに紹介します。
アプリ開発2026-06-24
三つの経路がそれぞれ番号を振っていた — versionCode を単一の真実から決めて配信を止めない設計
AI Studio がワンプロンプトでアプリを生成し Play の内部テストへそのまま上げられるようになった結果、人手・CI・エージェントの三経路が別々に versionCode を採番して衝突するようになりました。番号を単一の真実から決め、アップロード前に照合するガードまでを実装つきで整理します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →