Blog / Flutter

リリースビルドだけ起動即クラッシュした話

AGP 9 の R8 が WorkManager の生成クラスを消していた

2026年08月16日 公開 / Flutter ・ Android ・ R8 ・ WorkManager

Play で公開したアプリが、起動した瞬間に落ちるようになりました。手元の debug ビルドでは何ともありません。原因にたどり着くまでに遠回りしたので、同じ症状の人が検索で辿り着けるように記録を残します。結論から書くと、Android Gradle Plugin 9 系がリリースビルドで R8 をデフォルトで有効にすることが原因でした。

01 — 症状

Dart のコードに到達する前に死ぬ

リリースビルドを実機に入れて起動すると、スプラッシュも出ずに落ちます。 adb logcat を取ると、次の2行が出ていました。

Unable to get provider androidx.startup.InitializationProvider
Failed to create an instance of androidx.work.impl.WorkDatabase

厄介なのは、これが Flutter / Dart のコードが動き始める前に起きている点です。 Dart 側で try/catch をいくら書いても捕まりません。 クラッシュレポートにも Dart のスタックトレースが出ないので、 アプリのコードを疑っているうちは永遠に見つかりません。

02 — 真因

AGP 9 はリリースビルドで R8 が既定で有効

android/settings.gradle.kts で使っていた Android Gradle Plugin のバージョンは 9.0.1 でした。 AGP 9 系は、minifyEnabled を一行も書いていなくてもリリースビルドで R8(コード圧縮・難読化)が走ります。 証拠は分かりやすくて、ビルドすると mapping.txt が勝手に生成されています。

WorkManager と Room は、実行時にリフレクションで WorkDatabase_Impl のような 生成クラスを取りに行きます。R8 から見ると「どこからも呼ばれていないクラス」なので、 削除するか名前を変えてしまいます。結果、起動時の初期化で Room のデータベースが作れずに落ちます。

自分は WorkManager を直接使っていませんでした。引き込んでいたのは firebase_messaging(FCM)です。FCM を後から追加したので、 「前は起動できたのに、あるときから落ちるようになった」という体感とも一致しました。 debug ビルドで再現しなかったのは、単に debug では R8 が走らないからです。

03 — 修正

まず R8 を明示的に切る

app/android/app/build.gradle.ktsbuildTypes.release に、 暗黙の既定値に頼らず明示的に書きました。

buildTypes {
    release {
        isMinifyEnabled = false
        isShrinkResources = false
    }
}

これで実機のリリースビルドが起動するようになりました。 APK は 62MB から 69MB に増え、mapping.txt は生成されなくなります。 サイズと引き換えに、まず確実に起動する状態を取り戻した形です。

04 — 教訓

リリース挙動は実機のリリースビルドでしか分からない

検証は実機のリリースでflutter build apk --releaseadb installadb logcat。エミュレータや debug では再現しません。
暗黙の既定値を疑うツールのメジャーバージョンを上げたとき、書いていない設定の既定値が変わっていることがあります。
R8 を戻すなら keep ルールから再度有効にするなら、WorkManager・Room・Firebase の keep ルールを過不足なく書き、実機リリースで起動確認してから。漏れると別の箇所で同じ壊れ方をします。

このクラッシュはとりまトークで起きたものです。

Follow

こういう記録を置いています

個人開発でつまずいた話や、作りかけのものは Instagram(@kenpiro1012)と note にも置いています。 記事の一覧は記事ページにまとまっています。