I'm currently developing a simple KMM module, which needs Context
in order to perform some operations. I am aware of ways to achieve that with extending Application
class and making dependency injection. What am I trying to do right now - to make this module available out of the box with no need to modify manifest
or make manual injection on start up. I am just wondering is it a bad practice to make something like so:
@SuppressLint("StaticFieldLeak")
object SomeUtil {
private val context = Activity().applicationContext
}
Since applicationContext
return the Context
for the whole app and we're initializing it once will there be a leak? Or are there some other points not to make it?
Maybe there are some other possibilities to get app context from the module? I've seen some examples of retrieving it from threads, but as I understand this will be (or is already) deprecated.
UPD: This causes an error. Activity()
seems to be null
. So any ideas how to achieve that without DI and "MyApplication"?
This is a common problem in android libraries - how to get the app context without having access to the application codebase? It's why you often init libraries with something like SharedPrefHelper.init(applicationContext)
in your Application.onCreate()
As KMM shared code is a library you get a similar problem. Android app startup is an androidx lib built to solve this (as well as improving startup performance).
Rough sample (everything in shared code):
// In androidMain
class MySqlDelightInitialiser : Initializer<SqlDriver> {
override fun create(context: Context): SqlDriver {
val driver = createDriver(context)
MyLibraryObject.init(context, driver)
return driver
}
override fun dependencies(): List<Class<out Initializer<*>>> {
return emptyList()
}
}
// In androidMain/AndroidManifest
<application>
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.sql-delight-initialiser"
android:exported="false"
tools:node="merge"
tools:replace="android:authorities"
>
<meta-data
android:name="my.package.SqlDelightInitialiser"
android:value="androidx.startup"
/>
</provider>
</application>