FlutterアプリがGoogle Play版だけ起動直後にクラッシュする原因とWorkManager・AdMob関連の修正方法

Android開発

Flutterで開発したAndroidアプリが、デバッグ版では正常に動作するにもかかわらず、Google Playのクローズドテスト版やReleaseビルドだけ起動直後にクラッシュするケースがあります。特にlogcatに「androidx.startup.InitializationProvider」「androidx.work.WorkManagerInitializer」「androidx.work.impl.WorkDatabase」が表示される場合、WorkManager自体ではなく、Releaseビルド時の依存関係やコード最適化が原因になっていることがあります。

この記事では、google_mobile_adsを利用したFlutterアプリでWorkManager関連の起動クラッシュが発生した場合に確認すべきポイントと、build.gradle.ktsやproguard-rules.proなどの具体的な修正方法を解説します。

WorkDatabaseクラッシュで最も疑うべき原因はR8による最適化

「Unable to get provider androidx.startup.InitializationProvider」「Failed to create an instance of class androidx.work.impl.WorkDatabase」というエラーの場合、最も可能性が高い原因のひとつがReleaseビルド時に有効になるR8(コード縮小・難読化)です。

FlutterのdebugビルドではR8が動作しないため問題が発生せず、Google Playへ公開するReleaseビルドでのみ、WorkManagerやAndroidX Startupが必要とするクラス情報が削除・変更されることがあります。

google_mobile_adsは内部的にGoogle Mobile Ads SDKを利用しており、そのSDK内部でAndroidX StartupやWorkManager関連の依存関係が追加される場合があります。そのため、広告コードを削除せずに修正する場合は、まずReleaseビルド時の保持設定を確認するのが有効です。

proguard-rules.proにWorkManager関連の保持設定を追加する

まずAndroidフォルダ内のproguard-rules.proを開き、以下の設定を追加します。

-keep class androidx.work.** { *; }
-keep class androidx.startup.** { *; }
-keep class androidx.lifecycle.** { *; }

この設定により、R8によってWorkManagerやAndroidX Startupのクラスが削除・変換されることを防ぎます。

特にWorkDatabaseは内部的にRoom Databaseを利用して生成されるため、関連クラスの情報が不足するとInitializationProviderの生成時に失敗する場合があります。

build.gradle.ktsでR8設定を確認する

次にandroid/app/build.gradle.ktsを確認します。Releaseビルドでminifyが有効になっている場合、proguard設定が正しく読み込まれているか確認してください。

android {
    buildTypes {
        release {
            isMinifyEnabled = true
            isShrinkResources = true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
}

もしproguard-rules.proが指定されていない場合、追加したkeep設定が適用されません。

一時的な原因切り分けとして、以下のようにR8を無効化してReleaseビルドを試す方法もあります。

release {
    isMinifyEnabled = false
    isShrinkResources = false
}

この状態で起動する場合、ほぼ確実にR8による削除・難読化が原因です。

WorkManagerのバージョン固定だけでは解決しない理由

WorkManagerを2.9.1など特定バージョンへ固定する方法を試しても改善しない場合、原因はバージョン競合ではなく、Releaseビルド時のクラス保持問題である可能性が高くなります。

例えばpubspec.yamlでgoogle_mobile_adsを追加した場合、Flutter側から直接WorkManagerを利用していなくても、Android側の依存関係としてWorkManagerやAndroidX Startupが追加されます。

そのため「自分はWorkManagerを使っていないから関係ない」と考えず、Google Mobile Ads SDKが利用する内部処理として確認する必要があります。

AndroidManifest.xmlでInitializationProviderを確認する

AndroidManifest.xmlにも確認ポイントがあります。通常はAndroidX Startupが自動的にInitializationProviderを登録しますが、手動設定や削除設定がある場合は問題になります。

android/app/src/main/AndroidManifest.xml内で以下のような設定がないか確認してください。

<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    android:exported="false"
    tools:node="remove" />

もしtools:node=”remove”などでInitializationProviderを削除している場合、WorkManagerの自動初期化が正常に動作しなくなる可能性があります。

Flutter側のMobileAds初期化方法も確認する

main.dartではMobileAds.instance.initialize()を呼び出しますが、Androidアプリ起動直後のクラッシュの場合、この処理より前の段階でAndroidネイティブ側が失敗している可能性があります。

一般的には以下のようにWidgetsFlutterBinding.ensureInitialized()を先に実行します。

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await MobileAds.instance.initialize();
  runApp(const MyApp());
}

ただし今回のようにandroidx.startup.InitializationProviderで落ちている場合は、FlutterコードよりAndroidビルド設定側を優先して確認する必要があります。

Google Play版だけ落ちる場合の確認手順

Release版だけクラッシュする場合は、以下の順番で確認すると原因を特定しやすくなります。

確認項目 内容
1 R8を無効化してReleaseビルドする
2 起動できた場合proguard設定を追加する
3 WorkManagerとAndroidX Startupのkeep設定を確認する
4 google_mobile_adsのバージョンを確認する
5 Gradleキャッシュを削除して再ビルドする

例えば、R8無効化で正常起動するなら、広告SDKを削除する必要はなく、必要なクラスを保持する設定を追加するだけで解決できる可能性があります。

まとめ|FlutterのAdMob利用時にWorkManagerクラッシュしたらR8設定を最初に確認する

FlutterアプリがGoogle Play版だけ起動直後にクラッシュし、「androidx.startup.InitializationProvider」「WorkManagerInitializer」「WorkDatabase」がログに出る場合、最も疑うべきなのはReleaseビルド時のR8によるクラス削除や難読化です。

WorkManagerのバージョン変更だけで直らない場合は、proguard-rules.proへAndroidX StartupやWorkManagerのkeep設定を追加し、Releaseビルド設定を確認してください。

google_mobile_adsを利用している場合でも、広告機能を削除する必要はありません。Android側の依存関係とReleaseビルド設定を正しく調整することで、AdMobを維持したままGoogle Play版を正常起動できる可能性があります。

コメント

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