Heisenberg
Heisenberg

Reputation: 3193

Android Realm from UI thread

As I have noticed Realm database for Android does not support passing objects between threads. So my question is - should I run Realm transactions on UI thread or should I create some workaround?

Currently I am executing query on separate thread and execute some kind of workaround for the issue that basically replicates Realm object:

Address.detach(realm.copyToRealm(address));

TL;DR

Is running Realm queries on UI thread a performance and UX hit?

Upvotes: 1

Views: 4181

Answers (1)

atomontage
atomontage

Reputation: 105

Running Realm queries on UI thread is not really a performance hit unless you query for much data.

Example 1:

  • you query for SomeRealmObject on UI thread;
  • you access its fields then via corresponded getter methods;

The query itself should be fast enough. But as you access the returned object(s) Realm performs some magic: if its the first time you access this data, then its getting read from the disk. Otherwise it can already be cached so reading the value should not be a performance problem.

Example 2:

  • you query for SomeRealmObject on WORKER thread;
  • you do additional parsing or any other work on this thread;
  • you return the SomeRealmObject to the main thread. This is completely ok as Realm does support passing RealmObjects between different threads. (As stated in the official docs: https://realm.io/docs/java/latest/#threading)
  • then you work with this object in the main thread.

In both examples you do some work with the returned object. The main thing to remember is that if your object contains many fields and nested RealmObjects (and\or a RealmList) and you desperately need to read them all - then you better do it on a worker thread. Option 2 is to preload the data into memory and then to work on it. The thing is that Realm does not store data in your java heap (thats why if you try to read variables values while debugging it may read as null even if getters return data). But you can ask it to do so with Realm.copyFromRealm(yourRealmObject). This will return unmanaged RealmModel (a RealmObject or something else what you feed the method with). And the data will be stored in this new object.

TL;DR Just querying the database in the UI thread may be a performance hit if your query is heavy enough and your DB is large. This includes further data accessing from returned RealmModel (RealmObject or RealmResults).

Option 1: do all work in separate threads and pass some parsed data back;

Option 2: query your db and preload all data from separate thread and work with your data in the UI thread as if it was just an Object with some fields in it.

Upvotes: 3

Related Questions