How to properly separate Realm from the rest of the app?

和自甴很熟 提交于 2020-01-16 11:26:11

问题


In my app I am trying to use MVVM with repositories databases and all that. I like to keep all my external dependencies and such separate and compartmentalized into their own files/modules so that they can easily be replaced or swapped out.

With Realm I could make this work really well by using unmanaged objects. I can have a RealmHelper class for example which just opens a realm instance, queries or performs some transaction and then closes the realm and returns an object.

So how can I accomplish something similar with managed objects? The problem is in this case that you have to know when to close the realm. The obvious solution here I think is to let the database know when you are done with it, but this seems like a tedious and unoptimized solution. Is there another better way?


回答1:


So I have attempted to come up with a solution to this myself. I haven't tested it very well yet but my idea is basically to modify the LiveRealmResults file from the official example to let the caller (RealmHelper for example) know when it changes states between inactive and active. When it is active the caller will open the realm and pass in the results. When it changes to inactive the caller will close the realm. This is what my LiveRealmResults looks like:

@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()
    }
}

It will be used like so:

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()
        })
    }
}

This method at least allows me to keep all realm logic in the RealmHelper, only exposing LiveData and not RealmResults. Whenever the LiveData is inactive the Realm is closed. In my example I'm returning RealmObject but I'm fine converting from RealmObject to normal object so I'm am not concerned with that part for this example.



来源:https://stackoverflow.com/questions/59076757/how-to-properly-separate-realm-from-the-rest-of-the-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!