【问题标题】:How to properly separate Realm from the rest of the app?如何正确地将 Realm 与应用程序的其余部分分开?
【发布时间】:2019-11-27 18:49:29
【问题描述】:
在我的应用程序中,我尝试将 MVVM 与存储库数据库以及所有这些一起使用。我喜欢保留我所有的外部依赖项,并将它们分开并划分到它们自己的文件/模块中,以便可以轻松地替换或换出它们。
使用 Realm,我可以通过使用非托管对象来很好地完成这项工作。例如,我可以有一个 RealmHelper 类,它只打开一个领域实例,查询或执行一些事务,然后关闭领域并返回一个对象。
那么我怎样才能用托管对象完成类似的事情呢?在这种情况下,问题在于您必须知道何时关闭领域。我认为这里显而易见的解决方案是让数据库知道您何时完成它,但这似乎是一个乏味且未经优化的解决方案。还有其他更好的方法吗?
【问题讨论】:
标签:
android
kotlin
mvvm
realm
clean-architecture
【解决方案1】:
所以我试图自己想出一个解决方案。我还没有很好地测试它,但我的想法基本上是修改官方示例中的 LiveRealmResults 文件,以让调用者(例如 RealmHelper)知道它何时在非活动和活动之间更改状态。当它处于活动状态时,调用者将打开领域并传递结果。当它变为非活动状态时,调用者将关闭领域。这就是我的 LiveRealmResults 的样子:
@MainThread
class LiveRealmResults<T : RealmModel>(
private val getResults: () -> RealmResults<T>,
private val closeRealm: () -> Unit
) : LiveData<List<T>>() {
private var results: RealmResults<T>? = null
private val listener = OrderedRealmCollectionChangeListener<RealmResults<T>> {
results, _ ->
this@LiveRealmResults.value = results
}
override fun onActive() {
super.onActive()
results = getResults()
if (results?.isValid == true) {
results?.addChangeListener(listener)
}
if (results?.isLoaded == true) {
value = results
}
}
override fun onInactive() {
super.onInactive()
if (results?.isValid == true) {
results?.removeChangeListener(listener)
}
removeObserver()
}
}
会这样使用:
class RealmHelper() {
fun getObjects(): LiveData<List<Objects>> {
var realm: Realm? = null
return LiveRealmResults<Objects>(getResults = {
realm = Realm.getDefaultInstance()
realm!!.where<Objects>().findAll()
}, removeObserver = {
realm?.close()
})
}
}
这种方法至少允许我将所有领域逻辑保留在 RealmHelper 中,只暴露 LiveData 而不是 RealmResults。每当 LiveData 处于非活动状态时,Realm 就会关闭。在我的示例中,我正在返回 RealmObject,但我可以很好地从 RealmObject 转换为普通对象,因此我不关心此示例的那部分。