Android:如何只创建一个DatabaseRepository.kt实例并在不同的活动中使用它?

Android: How to create only one instance of DatabaseRepository.kt and use it in different activities?

EDIT: I NEED TO PASS A CONTEXT AS A PARAMETER TO THE CLASS

(DataStorerepository是一样的class,别搞混了)

我有两项活动,AB 以及一项 repository。 Activity A 打开 activity B 和 activity B 保存数据在 repository(DataStore 的一部分android 喷气背包)。

我在两个活动中都使用 LiveData 来观察 DataStore 中的数据变化。

从 activity B 更新 DataStore 中的新值后,activity B 中的 LiveData 获得新的更新值正如预期的那样。但是当我 return 回到 activity ALiveData 获取旧数据(期待新的更新数据)。

我意识到它正在发生,因为我在两个活动中创建了 repository 的两个实例。

我怎样才能只创建一个 repository class 的实例并在两个活动中使用它?如果有更好的方法,那么也欢迎该解决方案。

可以使用单例设计模式吗? 如果是:

class DataSource private constructor(private var mP1: Any?, private var mP2: Any?) {

fun setParam1(p1: Any) {
    mP1 = p1
}

fun setParam2(p2: Any) {
    mP2 = p2
}

companion object {
    private var mInstance: DataSource? = null
    fun getInstance(p1: Any, p2: Any): DataSource {
        if (mInstance == null)
            mInstance = DataSource(p1, p2)
        return mInstance
    }
}
}

我在 Android Studio 中编写了这个模型并将其转换为 kotlin,我不知道它是否是 Kotlin 中的有效代码。

有 2 个选项,要么在第一次调用该函数时将参数发送到 getInstance,然后用空值调用它 如:

//First time calling:
DataSource mMyInstance = DataSource.getInstance(param1, param2);
 //Second time calling:
 DataSource mMyInstance2 = DataSource.getInstance(null,null);

或者使用设置函数并让您的 getInstance 不带任何参数。 请注意,选择选项 1 会使您使用无用的参数调用 getInstance,但请确保您在选择选项 2 时不要忘记设置任何需要的参数可能会有更清晰的“getInstance”调用,但会强制您始终设置参数,在我的意见是 2

中更糟糕的选择

虽然 @DanBaruch 提到的传统单例模式有效,但 Kotlin 有一个很棒的关键字 object,您可以通过它在整个应用程序中创建单例实例。

object DatabaseRepository{
    private lateinit var context: Context

    fun setAppContext(context: Context){
        this.context = context
    }
}

要从 Application class 设置 context,请执行以下操作,

DatabaseRepository.setAppContext(this)

在 kotlin 中,有两种方法可以创建 Singleton

  1. 使用 object 关键字 - 有了这个,我们可以在构造函数中使用任何参数。

  2. 或者我们可以创建一个单例class,像这样:


class DbRepository () {

    companion object {
        private var instance: DbRepository? = null

        fun getInstance(context: Context): DbRepository {
            return instance ?: synchronized(this) {
                instance ?: DbRepository().also { instance = it }
            }
        }
    }

}


基于静态引用的单实例并将Context作为class参数传递导致内存泄漏。另一方面,您可以使用 Application class 创建一个必需的实例 class

class YourApp : Application(){
    val repository by lazy { YourRepository(this) }
}

并在其他地方使用 (context.applicationContext as YourApp).repository 访问它。并且不要忘记在清单

中声明 android:name=... 申请

由于 object 关键字不允许参数,我建议使用像 Dagger/Hilt 这样的依赖注入来创建一个单例并将其注入到您的视图模型中。

official documentation 值得一读。

如果您还没有使用依赖注入框架的经验,您应该先阅读该主题,然后再决定是否要将 DI 集成到您的应用程序代码中。