Hyperion-Android
Hyperion-Android copied to clipboard
[Bug] Crash plugin doesn't play nice with Application class init logic
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.
I just ran into the same Problem. The Code that causes the application to crash lives in one of my dagger (using Hilt) modules.
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:
https://github.com/willowtreeapps/Hyperion-Android/blob/8bb1e83adfcb0e349681b372e89bd9c23c832123/hyperion-crash/src/main/AndroidManifest.xml#L1-L13
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
.