Android Kotlin Realm Proper Way of Query+ Return U

2019-02-20 14:45发布

问题:

What is the proper way of querying and returning an unmanaged result of items with realm, everything in the background thread?. I'm using somethibf like this:

return Observable.just(1)
                .subscribeOn(Schedulers.io())
                .map {
                    val realm = Realm.getDefaultInstance()
                    val results = realm.where(ItemRealm::class.java)
                            .equalTo("sent", false).findAll()

                    realm to results
                }
                .map {
                    val (realm, results) = it
                    val unManagedResults = realm.copyFromRealm(results)
                    realm.close()
                    unManagedResults
                }
    }

And then chaining this observable with another one that will post the results to a server.

The solution working, although is a bit ugly on this aspects:

  • No proper way of wrapping the realmQuery in an observable, because there is no way of opening a realInstance in a background thread without this kind of cheat (at least that i know about), so i need to use this fake observable Observable.just(1).
  • Not the best place to open and close Realm instances, inside first and second map

  • I don't know if it is guaranteed that the realm instance is closed after all the items have been copied.

So what is the proper way of Query and Return unmanaged results on the background thread (some context, i need this to send the results to a server, in the background and as this task is totally independent from my app current data flow, so it should be off the main thread).

Suggested Version:

return Observable.fromCallable {
            Realm.getDefaultInstance().use { realm ->
                realm.copyFromRealm(
                        realm.where(ItemRealm::class.java)
                                .equalTo(ItemRealm.FIELD_SEND, false).findAll()
                )
            }
        }

回答1:

This is how you would turn your Realm objects unmanaged:

    return Observable.defer(() -> {
        try(Realm realm = Realm.getDefaultInstance()) {
            return Observable.just(
                realm.copyFromRealm(
                    realm.where(ItemRealm.class).equalTo("sent", false).findAll()
                )
            );
        }
    }).subscribeOn(Schedulers.io());

Although this answer is Java, the Kotlin answer is just half step away.