0

We use a subclassed Application object, like this:

class MyApp : Application() {
    init {
        instance = this
    }

    ...

    companion object {
        lateinit var instance: MyApp
            private set
    }
}

...which should get initialized before any other components of the app are launched (Activities, Services, etc). And for 99.99% of our users, everything works correctly.

However, there's a crash that we see for just a few users, that looks like this:

Exception java.lang.RuntimeException:
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:4051)
  at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:4325)
  at android.app.servertransaction.LaunchActivityItem.execute (LaunchActivityItem.java:101)
  at android.app.servertransaction.TransactionExecutor.executeCallbacks (TransactionExecutor.java:135)
  at android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.java:95)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2574)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loopOnce (Looper.java:226)
  at android.os.Looper.loop (Looper.java:313)
  at android.app.ActivityThread.main (ActivityThread.java:8757)
  at java.lang.reflect.Method.invoke
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:571)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1067)
Caused by kotlin.UninitializedPropertyAccessException: lateinit property instance has not been initialized
  at mypackage.MyApp$Companion.getInstance (MyApp.kt:312)
  at mypackage.MyActivity.<init> (MyActivity.kt:72)
  at java.lang.Class.newInstance
  at android.app.AppComponentFactory.instantiateActivity (AppComponentFactory.java:95)
  at androidx.core.app.CoreComponentFactory.instantiateActivity (CoreComponentFactory.java:45)
  at android.app.Instrumentation.newActivity (Instrumentation.java:1328)
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:4038)

Note in the stack trace that MyActivity attempts to access MyApp.instance, but apparently it hasn't been initialized! This would imply that the Activity is getting launched before the Application class was instantiated (?)

What could be going on?

Dmitry Brant
  • 7,612
  • 2
  • 29
  • 47
  • Have you tried initialising the lateinit variable in `onCreate`?. Also, you could simply use `Context.applicationContext` in most cases. – Darshan Jun 16 '23 at 14:07
  • Yes, this is why we moved it to `init`, which should happen even earlier than `onCreate`. – Dmitry Brant Jun 16 '23 at 14:19
  • In an Activity, you should be using this.application as MyApp to get the application object. My guess is here that you ran into some kind of race condition in the framework, perhaps the Application object is initialized lazily? Or perhaps on separate threads/coroutines? Have you tried putting breakpoints in the activity's onCreate, the init here, and seeing the sequence of events? – Gabe Sechan Jun 16 '23 at 14:52
  • "In an Activity, you should be using this.application as MyApp to get the application object" - Why would that be any different? If `this.application` is nonnull, it means the Application object was instantiated, and its `init` block was called. Would it ever be a _different_ Application object than the one in our `instance` singleton? (To reiterate, this crash is happening for a very small number of users, and we haven't reproduced it.) – Dmitry Brant Jun 16 '23 at 15:04
  • Pretty sure this has something to do with an app restart after the app has been killed while in background. In the Android developer settings, set the background processes limit to 0. Open your app, suspend it, open a few other apps and wait 10 seconds. Then open your app again go simulate this situation. – Alexander Hoffmann Jun 16 '23 at 15:16
  • @AlexanderHoffmann Very interesting idea, but even with those constraints my test devices still behave properly - the Application object always gets initialized before anything else :( – Dmitry Brant Jun 16 '23 at 18:53

0 Answers0