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



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

(DataStorerepository是同一类,不要混淆)

我有两个活动,AB和一个repository。活动A打开活动B,活动Brepository中保存数据(DataStore是android jetpack的一部分)。

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

从活动B更新DataStore中的新值后,活动B中的LiveData按预期获得新的更新值。但是,当我返回到活动ALiveData得到旧的数据(期望新的更新的数据)。

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

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

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

的一个实例
class YourApp : Application(){
val repository by lazy { YourRepository(this) }
}

,并通过(context.applicationContext as YourApp).repository在其他地方访问它。不要忘记在manifest

中声明android:name=...

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

object DatabaseRepository{
private lateinit var context: Context
fun setAppContext(context: Context){
this.context = context
}
}

Application类设置context

DatabaseRepository.setAppContext(this)

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

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

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

的最差选择。

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

官方文档值得一读。

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