web-dev-qa-db-fra.com

Classe d'application Kotlin Singleton

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.

35
johnny_crq

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.

33
nitrico

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.

73
Kirill Rakhman
    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()
        }
    }
11
Raja Jawahar

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.

3
Michael