首页 > 解决方案 > 在 Kotlin 中创建单例类

问题描述

我想在 kotlin 中创建可以在将来发布的单例类。

这是代码。

companion object {
        // Singleton prevents multiple instances of repository opening at the
        // same time.
        @Volatile
        private var INSTANCE: AudioRepo? = null

        @Volatile
        private var counter: Int = 0

        @JvmStatic
        fun release() {
            synchronized(this) {
                // if counter is already 0 some sort of error has occurred
                if (counter == 0)
                    throw IllegalStateException("Counter variable is 0")
                counter--
                if (counter == 0) {
                    INSTANCE!!.destroy()
                    INSTANCE = null
                }
            }
        }

        @JvmStatic
        fun get(context: Context): AudioRepo {
            // if the INSTANCE is not null, then return it,
            synchronized(this) {
                counter++
                return INSTANCE ?: run {
                    val instance = AudioRepo(context.applicationContext as Application)
                    INSTANCE = instance
                    instance
                }
            }
        }
    }

请检查这是好还是我做错了什么。

这里的想法是,如果使用 get 获取实例,则需要使用 release() 释放它。计数器确定何时清除对象。

更新 由于大多数人似乎很困惑为什么我需要这种方法。让我解释。

AudioRepo 类需要在 UI 和 Service 中为 Singleton。由于我不能使用任何带刀柄的范围(我猜)使其成为单例,所以我使用了这种方法。

我不能单独使用 kotlin 对象类,我需要释放音频 repo 所包含的 Couroutine Scope 并取消注册 Content Observer。

我不能使用自动关闭(据我了解),因为我使用了 Jet Pack compose 和 In Service 的子可组合实例。

标签: androidkotlin

解决方案


我认为您应该考虑我的解决方案:

open class Singleton<out T : Any>(creator: () -> T) {
    private var creator: (() -> T)? = creator
    @Volatile
    private var instance: T? = null
    fun getInstance(): T {
        val i = instance
        if (i != null)
            return i
        return synchronized(this) {
            val i2 = instance
            if (i2 != null)
                i2
            else {
                val created = creator!!()
                instance = created
                creator = null
                created
            }
        }
    }
}

- - 例子

class ImageLoader private constructor(){
    companion object : Singleton<ImageLoader>(::ImageLoader)
}

推荐阅读