如何将Realm与应用程序的其余部分正确分开?

时间:2019-11-27 18:49:29

标签: android kotlin mvvm realm clean-architecture

在我的应用程序中,我尝试将MVVM与存储库数据库一起使用。我喜欢保留所有外部依赖关系,并将它们分开并划分到各自的文件/模块中,以便可以轻松地替换或替换它们。

使用Realm,我可以通过使用非托管对象来使这项工作非常好。我可以有一个RealmHelper类,例如,它仅打开一个领域实例,查询或执行一些事务,然后关闭该领域并返回一个对象。

那么我该如何对托管对象完成类似的工作?问题是在这种情况下,您必须知道何时关闭领域。我认为,最明显的解决方案是在完成数据库处理后让数据库知道,但这似乎是一个乏味且未优化的解决方案。还有另一种更好的方法吗?

1 个答案:

答案 0 :(得分:0)

所以我尝试自己解决这个问题。我尚未对其进行很好的测试,但是我的想法基本上是从官方示例修改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处于非活动状态时,领域都会关闭。在我的示例中,我将返回RealmObject,但可以将RealmObject转换为普通对象,因此对于此示例,我不必担心该部分。