Класс приложения Kotlin Singleton

Поэтому в android я хочу сделать свой класс приложения синглом.

Сделав это так:

object MyApplication: Application(){}

не будет работать. После эррос бросается во время выполнения:

java.lang.IllegalAccessException: private com....is not accessible from class android.app.Instrumentation.

Выполнение этого также невозможно:

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_         
    }
}

Итак, как я могу получить экземпляр класса приложения в моем приложении, хотел бы использовать MyApp.instance() вместо (applicationContext as MyApp).

Также объяснение, почему я хочу это: у меня есть классы в моем приложении, например, SharedPreference Singleton, который инициализируется контекстом и как его одноэлемент, не может иметь аргументов.

Ответ 1

Если вы хотите использовать его для доступа к некоторым статическим свойствам, которые у вас есть: у вас будет только один экземпляр вашего приложения, поэтому просто используйте имя, которое вы дали классу. Не беспокойтесь о том, что это не настоящий синглтон, вы можете использовать его таким же образом.

Пример:

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

}

Затем вы можете использовать MyApp.CONSTANT и MyApp.typeface любом месте вашего приложения.

-

Если вы хотите использовать его в качестве контекста приложения, вы можете создать свойство расширения для Context:

val Context.myApp: MyApp
        get() = applicationContext as MyApp

Затем вы можете использовать myApp чтобы получить контекст приложения в любом месте контекста.

Ответ 2

Вы можете сделать то же самое, что и в Java, то есть поставить экземпляр Application в статическое поле. У Kotlin нет статических полей, но свойства объектов объектно доступны.

class MyApp: Application() {

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

    companion object {
        lateinit var instance: MyApp
            private set
    }
}

Затем вы можете получить доступ к свойству через MyApp.instance.

Ответ 3

class AppController : Application() {

    init {
        instance = this
    }

    companion object {
        private var instance: AppController? = null

        fun applicationContext() : AppController {
            return instance!!
        }
    }

    override fun onCreate() {
        super.onCreate()

    }

Ответ 4

Вы не можете этого сделать, потому что Android создает экземпляр Application используя его конструктор без параметров.

Проблема, которую вы хотите решить, может быть легко решена с помощью DI. Просто создайте экземпляры с инжектором, чтобы Context мог быть введен в объекты как зависимость.