在 kotlin 中声明单例

Declaring singletons in kotlin

我有这段代码用于获取我的 Room 数据库的单例实例,但是在我的所有代码中,我在使用 Dao 时收到 lint 警告,它可能导致空指针异常,因为 getInstance 可以return 可为空的值

abstract class DatabaseInstance : RoomDatabase() {

    // ... Dao's

    companion object {
        private var INSTANCE: DatabaseInstance? = null

        fun getInstance(context: Context): DatabaseInstance? {
            if (INSTANCE == null) {
                synchronized(DatabaseInstance::class) {
                    INSTANCE = Room.databaseBuilder(context.applicationContext,
                        DatabaseInstance::class.java, "my_database.db")
                        .allowMainThreadQueries().fallbackToDestructiveMigration().build()
                }
            }
            return INSTANCE
        }

        fun destroyInstance() {
            INSTANCE = null
        }
    }
}

我尝试查看是否可以使用私有和 public 实例变量,其中 public 将具有自定义 getter 并执行 getInstance 的操作,但我无法将上下文传递给它.

因为 getInstance 真的永远不会 return null 我该如何调整才能消除 lint 错误?

不,我不想只抑制 lint 错误

您的 getInstance(Context) return 是可选类型。而是在 INSTANCE.

上使用 !! 运算符使其成为 return DatabaseInstance
fun getInstance(context: Context): DatabaseInstance {
    if (INSTANCE == null) {
        synchronized(DatabaseInstance::class) {
            INSTANCE = Room.databaseBuilder(context.applicationContext,
                DatabaseInstance::class.java, "my_database.db")
                .allowMainThreadQueries().fallbackToDestructiveMigration().build()
        }
    }
    return INSTANCE!!
}

但请记住,您的整体实现不是线程安全的。

我想你可以这样做:

companion object {
    private val instance: DatabaseInstance = DatabaseInstance()
    fun getInstance(): DatabaseInstance {
        return instance
    }
}

如果我有问题请纠正我,但我认为您的实例只会被初始化一次。

您可以利用 Elvis operator 到 return 非空 DatabaseInstance 并避免使用 !! 运算符:

private var INSTANCE: DatabaseInstance? = null

fun getInstance(context: Context): DatabaseInstance {
    return INSTANCE ?: synchronized(DatabaseInstance::class) {
        INSTANCE ?: Room.databaseBuilder(context.applicationContext, DatabaseInstance::class.java, "my_database.db")
                .allowMainThreadQueries()
                .fallbackToDestructiveMigration()
                .build()
                .also { INSTANCE = it }
    }
}

来源:Pro-tips for Room