Kotlin Singleton应用类

joh*_*crq 36 singleton android kotlin

所以在android中我想让我的应用程序类成为单例.

像这样:

object MyApplication: Application(){}
Run Code Online (Sandbox Code Playgroud)

不行.在运行时抛出以下错误:

java.lang.IllegalAccessException: private com....is not accessible from class android.app.Instrumentation.
Run Code Online (Sandbox Code Playgroud)

这样做也是不可能的:

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_         
    }
}
Run Code Online (Sandbox Code Playgroud)

那么如何才能在我的应用程序中随处获得应用程序类的实例,MyApp.instance()而不是使用(applicationContext as MyApp).

还解释了为什么我想要这个:我在我的应用程序中有类,例如,使用上下文初始化的SharedPreference Singleton,并且作为它的单例,不能有参数.

Kir*_*man 77

您可以执行与Java相同的操作,即将Application实例放在静态字段中.Kotlin没有静态字段,但对象中的属性是静态可访问的.

class MyApp: Application() {

    override fun onCreate() {
        super.onCreate()
        instance = this
    }

    companion object {
        lateinit var instance: MyApp
            private set
    }
}
Run Code Online (Sandbox Code Playgroud)

然后您可以通过酒店进入酒店MyApp.instance.

  • 什么是在底部使用`private set`? (3认同)
  • @Redman 因为我们只希望 MyApp 可以设置实例值 (3认同)
  • 它给出“ lateinit属性实例尚未初始化”的错误 (2认同)

nit*_*ico 33

如果您想使用它来访问某些静态属性,那么:您只有一个Application实例,所以只需使用您为该类提供的名称即可.不要担心它不是一个真正的单身人士,你可以用同样的方式使用它.

例:

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")
    }

}
Run Code Online (Sandbox Code Playgroud)

然后你可以使用MyApp.CONSTANT,并MyApp.typeface在您的应用程序的任何地方.

-

如果您想要将其用作应用程序上下文,则可以为Context创建扩展属性:

val Context.myApp: MyApp
        get() = applicationContext as MyApp
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用myApp在具有上下文的任何位置获取应用程序上下文.

  • @nitrico看起来不错,但我无法获得“ val Context.myApp:MyApp get()= applicationContext作为MyApp的一部分”可以正常工作。您能否再详细一点?这条线需要去哪里,以及如何在另一堂课中访问它? (2认同)

Raj*_*har 11

    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()
        }
    }
Run Code Online (Sandbox Code Playgroud)