3

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

DataStorerepository是同一个班,不要混淆)

我有两个活动,AB一个repository。ActivityA打开 Activity B, ActivityB将数据保存在repositoryDataStoreandroid jetpack 的一部分)中。

LiveData在这两个活动中都使用来观察DataStore.

DataStorefrom 活动B中更新新值后,活动LiveData中的B将按预期获取新的更新值。但是当我返回活动时ALiveData会获取旧数据(期待新的更新数据)。

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

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

4

5 回答 5

3

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

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

并在其他地方使用(context.applicationContext as YourApp).repository. 并且不要忘记android:name=...在manifest中声明申请

于 2021-02-11T09:43:11.620 回答
2

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

object DatabaseRepository{
    private lateinit var context: Context

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

要设置contextfromApplication类,请执行以下操作,

DatabaseRepository.setAppContext(this)
于 2021-02-11T09:17:08.593 回答
1

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

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

  2. 或者我们可以创建一个单例类,如下所示:


class DbRepository () {

    companion object {
        private var instance: DbRepository? = null

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

}


于 2021-02-11T09:21:37.480 回答
0

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

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 发送参数,然后使用 null 调用它,如下所示:

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

或者使用设置函数并保持你的 getInstance 没有参数。请注意,选择选项 1 会使您使用无用的参数调用 getInstance,但请确保您不会忘记设置任何需要的参数,而选择选项 2 可能会有更清晰的“getInstance”调用,但会强制您始终设置参数,其中我认为,是 2 中更糟糕的选择

于 2021-02-11T09:14:03.413 回答
0

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

官方文档值得阅读以开始使用。

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

于 2021-02-11T23:15:54.323 回答