Reputation: 4391
On Android I want to make my application class a singleton.
Making it like this:
object MyApplication: Application(){}
won't work. The following error is thrown at runtime:
java.lang.IllegalAccessException: private com....is not accessible from class android.app.Instrumentation.
Doing this is also not possible:
class MyApp: Application() {
private val instance_: MyApp
init{
instance_ = this
}
override fun onCreate() {
super.onCreate()
if (BuildConfig.DEBUG) {
Timber.plant(Timber.DebugTree());
}
}
companion object{
fun getInstance() = instance_
}
}
How can I get an instance of my application class everywhere in my app? I would like to use MyApp.instance()
instead of (applicationContext as MyApp)
.
Also an explanation why I want this: I have classes in my app. For example, a SharedPreference Singleton which is initialised with a context, and as it’s a singleton, it can't have arguments.
Upvotes: 56
Views: 58156
Reputation: 6972
class AppController : Application() {
init {
instance = this
}
companion object {
private var instance: AppController? = null
fun applicationContext() : AppController {
return instance as AppController
}
}
override fun onCreate() {
super.onCreate()
}
}
Upvotes: 21
Reputation: 623
If you want to use it to access some static properties you have there: You will only have one instance of your Application, so simply use the name you gave to the class. Don't worry about it not being an actual singleton, you can use it the same way.
Example:
class MyApp : Application() {
companion object {
const val CONSTANT = 12
lateinit var typeface: Typeface
}
override fun onCreate() {
super.onCreate()
typeface = Typeface.createFromAsset(assets, "fonts/myFont.ttf")
}
}
Then you can use MyApp.CONSTANT
and MyApp.typeface
anywhere in your app.
-
If what you want is to use it as an application context you can create an extension property for Context:
val Context.myApp: MyApp
get() = applicationContext as MyApp
Then you can use myApp
to get the the application context anywhere you have a context.
Upvotes: 50
Reputation: 43861
You can do the same thing you would do in Java, i.e. put the Application
instance in a static field. Kotlin doesn't have static fields, but properties in objects are statically accessible.
class MyApp: Application() {
override fun onCreate() {
super.onCreate()
instance = this
}
companion object {
lateinit var instance: MyApp
private set
}
}
You can then access the property via MyApp.instance
.
Upvotes: 123
Reputation: 54725
You cannot do that because Android creates an Application
instance using its parameterless constructor.
The problem you want to solve can be easily solved with DI. Just create instances with an injector so that the Context
can be injected into objects as a dependency.
Upvotes: 3