Donc, dans Android, je veux faire de ma classe d’application un singleton.
Faire comme ça:
object MyApplication: Application(){}
ne fonctionnera pas. Les erreurs suivantes sont lancées à l'exécution:
Java.lang.IllegalAccessException: private com....is not accessible from class Android.app.Instrumentation.
Ce n'est pas possible non plus:
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_
}
}
Alors, comment puis-je obtenir une instance de ma classe d'application partout dans mon application, voudrait utiliser MyApp.instance()
au lieu de (applicationContext as MyApp)
.
En outre, une explication de la raison pour laquelle je veux ceci: j'ai des classes dans mon application, par exemple, un Singleton SharedPreference qui est initialisé avec un contexte, et en tant que singleton, ne peut pas avoir d'arguments.
Si vous voulez tilisez-le pour accéder à certaines propriétés statiques vous avez là: vous ne disposez que d'une instance de votre application, utilisez donc simplement le nom que vous avez donné à la classe. Ne vous inquiétez pas du fait qu'il ne s'agisse pas d'un singleton, vous pouvez l'utiliser de la même manière.
Exemple:
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")
}
}
Ensuite, vous pouvez utiliser MyApp.CONSTANT
et MyApp.typeface
n'importe où dans votre application.
-
Si ce que vous voulez est pour l'utiliser comme contexte d'application, vous pouvez créer une propriété d'extension pour le contexte:
val Context.myApp: MyApp
get() = applicationContext as MyApp
Ensuite, vous pouvez utiliser myApp
pour obtenir le contexte de l'application partout où vous avez un contexte.
Vous pouvez faire la même chose que vous feriez en Java, c’est-à-dire mettre l’instance Application
dans un champ statique. Kotlin n'a pas de champs statiques, mais les propriétés des objets sont statiquement accessibles.
class MyApp: Application() {
override fun onCreate() {
super.onCreate()
instance = this
}
companion object {
lateinit var instance: MyApp
private set
}
}
Vous pouvez ensuite accéder à la propriété via MyApp.instance
.
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()
}
}
Vous ne pouvez pas faire cela car Android crée une instance Application
à l'aide de son constructeur sans paramètre.
Le problème que vous souhaitez résoudre peut être facilement résolu avec DI. Créez simplement des instances avec un injecteur afin que le Context
puisse être injecté dans des objets en tant que dépendance.