I am trying to save an Application instance and use in the constructor of databaseHelper, but when my activity tries to instantiate the databaseHelper I get the following exceptions:
FATAL EXCEPTION:
main Process: com.weatherupp.weatherupp, PID: 29092
java.lang.ExceptionInInitializerError
at com.weatherupp.weatherupp.ui.MainActivity.onCreate(MainActivity.kt:27)
[...]
Caused by: kotlin.UninitializedPropertyAccessException: lateinit
property instance has not been initialized
the code leading to the exception is the following:
MainActivity {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val provider = ForecastProvider()
[...]
}
ForecastProvider has the following companion object:
companion object {
val SOURCES = listOf(ForecastServer(), ForecastDb())
}
ForecastDb's constructor refers to an instance of ForecastDbHelper, whose constructor refers to App.instance, declared as follows:
class App : Application() {
companion object {
lateinit var instance: App
}
override fun onCreate() {
super.onCreate()
instance = this
}
}
If I comment all the code referring to the database, the app works using ForecastServer as the source of data, but the moment I try to refer to the database and hence to the App istance, Kotlin throws the UninitializedPropertyAccessException.
I have been looking at the code for hours, can't figure out what I am doing wrong. Any help is blessed, thank all of you in advance.
Cannot exactly pinpoint why your approach isn't working but I can suggest a fix:
You need a ForecastDb
in your MainActivity
. Your ForecastDb
needs a ForecastDbHelper
. Your ForecastDbHelper
needs the Application
instance.
So in your MainActivity
you do:
val helper = ForecastDbHelper(application as App)
val db = ForecastDb(helper)
and voila, you got your db ready.
This is called dependency injection and gives you more control over creation of the objects 'fetching' their dependencies themselves.
EDIT: Also check if you added your App
class as the Application
in the AndroidManifest.xml
like this::
<application
android:name=".base.App"
...