Lisa Anne
Lisa Anne

Reputation: 4595

Perform work on a different thread

I execute a Realm query,

then I need to perform a time consuming mapping of the result of the Realm query, consequently it needs to be done on a worker thread.

Finally I need the results on the main thread (because they update the UI).

But the following code (understandably) gives me an exception: "Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created."

val defaultInstance = Realm.getDefaultInstance()
val subscription = defaultInstance
            .where(Bar::class.java)
            .equalTo("foo", true)
            .findAllAsync()
            .asObservable()
            .filter { it.isLoaded && it.isValid }
            .map { defaultInstance.copyFromRealm(it) }

            // The following is a time consuming task, I need to perform it on another thread
            .observeOn(workerScheduler)
            .map { someComplexMapping(it) }

            // but the results are needed on the main thread (because it updates the UI) 
            .subscribeOn(mainThreadScheduler)
            .subscribe(observer)

Please how do I achieve what I need?

Upvotes: 0

Views: 81

Answers (2)

EpicPandaForce
EpicPandaForce

Reputation: 81588

val defaultInstance = Realm.getDefaultInstance()
val subscription = defaultInstance
        .where(Bar::class.java)
        .equalTo("foo", true)
        .findAllAsync()
        .asObservable()
        .subscribeOn(mainThreadScheduler)
        .filter { it.isLoaded && it.isValid }
        .observeOn(Schedulers.io())
        .map {
             Realm.getDefaultInstance().use { 
                 //it.refresh() // shouldn't be needed
                 it.copyFromRealm(it.where(Bar::class.java).equalTo("foo", true).findAll())
             }
        }
        // The following is a time consuming task, I need to perform it on another thread
        .observeOn(workerScheduler)
        .map { someComplexMapping(it) }

        // but the results are needed on the main thread (because it updates the UI) 
        .observeOn(mainThreadScheduler)
        .subscribe(observer)

Upvotes: 2

TokajiP
TokajiP

Reputation: 36

Create an Observable before the Realm query and put it into the UI thread with .observeOn(AndroidScheduler.mainThread()).
Run the Realm query and the other stuffs like you did before.

Upvotes: 1

Related Questions