Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Crash plugin doesn't play nice with Application class init logic #195

Open
frushlabo opened this issue Jun 30, 2020 · 2 comments
Open

Comments

@frushlabo
Copy link

Crash plugin seems to try to create its own application process when a crash is detected, this triggers all of my application class init logic to run, such as firebase then crashes the crash plugin :D

Not sure if there's a straight forward solution but interested to hear your thoughts

  Process: com.myapp:crash, PID: 13013
    java.lang.RuntimeException: Unable to create application com.myapp.MyApplication: java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process com.myapp:crash. Make sure to call FirebaseApp.initializeApp(Context) first.
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6846)
        at android.app.ActivityThread.access$1400(ActivityThread.java:267)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1981)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:237)
        at android.app.ActivityThread.main(ActivityThread.java:7770)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1047)
     Caused by: java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process com.myapp:crash. Make sure to call FirebaseApp.initializeApp(Context) first.
@CaptnBlubber
Copy link

I just ran into the same Problem. The Code that causes the application to crash lives in one of my dagger (using Hilt) modules.

@AlexKrupa
Copy link

Correct, Hyperion launches its crash activity in a separate :crash process, which causes Application class recreation.

You can work around this issue by initializing your dependencies in that same process.

Here's how you can do it using ContentProvider trick to initialize Firebase before Application.onCreate:

class HyperionCrashProcessWorkaround : ContentProvider() {

    private companion object {

        var isCreated = false

        // Workaround for ContentProvider being created twice:
        // https://issuetracker.google.com/issues/37045392
        fun ifFirstOnCreate(action: () -> Unit) {
            if (isCreated) return
            action()
            isCreated = true
        }
    }

    override fun onCreate(): Boolean {
        ifFirstOnCreate {
            initializeFirebase()
        }
        return false
    }

    private fun initializeFirebase() {
        FirebaseApp.initializeApp(checkNotNull(context))
    }

    // Default overrides to satisfy ContentProvider's API.
    override fun query(uri: Uri, projection: Array<out String>?, selection: String?, selectionArgs: Array<out String>?, sortOrder: String?): Cursor? = null
    override fun insert(uri: Uri, values: ContentValues?): Uri? = null
    override fun update(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array<out String>?) = 0
    override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?) = 0
    override fun getType(uri: Uri): String? = null
}

Add the provider AndroidManifest.xml:

<application>
    <provider
        android:name=".HyperionCrashProcessWorkaround"
        android:authorities="${applicationId}.HyperionCrashProcessWorkaround"
        android:exported="false"
        android:process=":crash"
        android:syncable="false"/>
</application>

Note the android:process value matching Hyperion's process here:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.willowtreeapps.hyperion.crash">
<application>
<activity
android:name=".CrashActivity"
android:theme="@style/hc_ActivityTheme"
android:noHistory="true"
android:excludeFromRecents="true"
android:process=":crash" />
</application>
</manifest>

Keep in mind that both of these can (and probably should) be defined only in debug sources, since Hyperion itself is usually added as debugImplementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants