LoginSignup
30
24

More than 5 years have passed since last update.

LeakCanaryとFirebaseを併用するとクラッシュする

Last updated at Posted at 2016-11-27

事象

FirebaseをLeakCanaryを併用するとLeakCanaryのプロセスが以下のログを出力しながらクラッシュします。

Caused by: java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process com.hogehoge:leakcanary.
Make sure to call FirebaseApp.initializeApp(Context) first.

LeakCanaryはアプリのメインプロセスとは別のプロセスで稼働しているのでアプリ自体はクラッシュしません(しばらくフリーズしますが)時と場合による。

原因

FirebaseはContentProviderを利用してライブラリの初期化を行っています。
この手法についてはこちらが詳しいです。

ContentProviderはデフォルトでマルチプロセスが無効となっているため、メインプロセス以外ではFirebaseが初期化されていない状態となってしまいLeakCanaryのプロセスで最初に示したエラーとなってしまいます。

このため、Firebaseに限らずContentProviderで初期化するアプローチを取っているライブラリは何らかの問題が発生する可能性があります。

対応方法

Firebaseには手動で初期化するためのAPIが用意されているのでそちらを使用してApplicationクラスの onCreate で初期化します。
ref: FirebaseApp  |  Firebase

@Override
public void onCreate() {
    // 必要に応じて他のオーバーロードと使い分ける
    FirebaseApp.initializeApp(this)
}

これで、とりあえずクラッシュは回避できますが、初期化のためのContentProviderは残っているため無駄に初期化処理が動いてしまいます。
なのでAndroidManifestに次の記述を追加して、Manifest MergerがContentProviderを追加するのを防ぎます。

<provider
        android:authorities="${applicationId}.firebaseinitprovider"
        android:name="com.google.firebase.provider.FirebaseInitProvider"
        tools:node="remove"/>

他にContentProviderを使用しているライブラリがあれば同様に tools:node="remove" を指定してAndroidManifestに追加されないようにしていきます。
その際、 android:authorities はなんでもいいのですが、 android:name は実際のものと一致している必要があります。
ライブラリのソースを見るか、マージ後のAndroidManifestから探して正しいものを指定してください。

例えば、拙作のライブラリKotprefの場合は次のように指定することで自動初期化用のContentProviderを無効化することができます。

<provider
        android:authorities="${applicationId}.KotprefInitProvider"
        android:name="com.chibatching.kotpref.KotprefInitProvider"
        tools:node="remove"/>
@Override
public void onCreate() {
    Kotpref.init(this)
}
30
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
24