EDIT: I NEED TO PASS A CONTEXT AS A PARAMETER TO THE CLASS
(DataStore
和repository
是同一类,不要混淆)
我有两个活动,A
和B
和一个repository
。活动A
打开活动B
,活动B
在repository
中保存数据(DataStore
是android jetpack的一部分)。
我在两个活动中都使用LiveData
来观察DataStore
中的数据变化。
从活动B
更新DataStore
中的新值后,活动B
中的LiveData
按预期获得新的更新值。但是,当我返回到活动A
LiveData
得到旧的数据(期望新的更新的数据)。
我意识到它正在发生,因为我在两个活动中都创建了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
。
-
使用
object
关键字-有了这个,我们可以在构造函数中有任何参数。 -
或者我们可以创建一个单例类,像这样:
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这样的依赖注入来创建一个单例并将其注入到视图模型中。
官方文档值得一读。
如果你还没有依赖注入框架的经验,你应该先阅读一下这个主题,然后再决定是否要把依赖注入集成到你的应用程序代码中。