Realm.io and asynchronous requests

We are starting to use Realm.io in the Android app project. But something that we don't like about the Realm.io API is the lack of an asynchronous way to query the database. In older projects, we used DbQuery and Sqlite, so we use to create database queries inside threads or AsyncTask . But itโ€™s quite alarming to see that in all the examples, the queries are executed in UiThread . Isn't that bad for application performance ?. We tried to make requests inside threads or AsyncTasks, but we get an error when accessing model objects back in UiThread, stating that we cannot access RealObjects in threads that were not the ones where they were requested. Here is a sample code:

 service.getDatabaseHelper() .with(getActivity()) //Context that I use to instance the Realm instance .onFinishQuery( new DatabaseHelper.IQueryGetCallback<UserRealm>() { @Override public void onGetResult(UserRealm[] results) { for(UserRealm aUser : results){ //Here is where it crashes Log.d("Log","Username -> "+aUser.getName()); } } }) .getUsersFromDb(); //....... //In our "DAO" class public void getUsersFromDb(){ new GetQueryTask() { @Override public UserRealm[] onQueryReadyToBeExecuted(Realm realmInstance) { RealmQuery<UserRealm> query = realmInstance.where(UserRealm.class); RealmResults<UserRealm> result = query.findAll(); // TODO hacer que devuelva un array ArrayList<UserRealm> users = new ArrayList<UserRealm>(); for (UserRealm u : result) { //Here we can read the RealObject fine users.add(u); } return users.toArray(new UserRealm[users.size()]); } }.execute(); } //Our abstract task that wraps all the instantiation-transaction behaviour public abstract class GetQueryTask<T extends RealmObject> extends AsyncTask<Void, Void, T[]> { @Override protected T[] doInBackground(Void... params) { //We tried to instantiate this class in several places, here //Send it as parameter through the AsyncTask //context is set in the with(Context ctx) method. Realm realm = Realm.getInstance(context); return onQueryReadyToBeExecuted(realm); } public abstract T[] onQueryReadyToBeExecuted(Realm realmInstance); @Override protected void onPostExecute(T[] result) { mCallback.onExecute(result); } } 

Our main problem is not the โ€œerrorโ€ of this code, but the fact that we make requests in UiThread, like the developers of Realm.io, in our examples. If so, then all this code will no longer be needed to execute asynchronous requests.

+5
source share
2 answers

Kingdom Christian is here. You are correct that the requests are currently being executed on the thread on which they are used, which could potentially adversely affect the performance of the user interface thread. Nevertheless, we are acutely aware of this and are actively working to ensure that it is possible to move query results across threads.

At the same time, requests in Realm are quite fast even with reasonably large amounts of data, and due to this, only loading the data that you actually use can be very effective even when launched in a user interface stream.

I would advise you to try it with any data size that seems reasonable to you, and test your performance (preferably on an older device :)). It is also possible to do tricks, such as adding indexes to keys, making a heavy request on a background thread, sending keys to a user interface thread, and requesting them there. This is a gang, but in some cases it will work - unfortunately, not for lists.

+7
source

realm 0.84 now supports asynchronous requests.

You can try adding 'io.realm: realm-android: 0.84.0-SNAPSHOT' to your build.gradle. There are several new methods.

  • findAllAsync
  • findAllSortedAsync
  • findFirstAsync

You must add addChangeListener (RealmChangeListener) to RealmResult to receive a notification when the request is complete.

Documentation: https://realm.io/docs/java/latest/#asynchronous-queries

+5
source

Source: https://habr.com/ru/post/1210502/


All Articles