What is the correct way to solve multithreading and Realm problems?

In my Android application, I have a data access level where I have the following property for each data warehouse class

Realm realm = Realm.getDefaultInstance();

My problem is when I try to call any method of storing data from another thread. Then i get

Realm objects can only be accessed in the stream that was created.

I read that I have to create a new instance of Realm in a new thread. The problem is that the data access level does not know a word, it does not know whether it called the main or split, and it seems to me that it will smell like adding logic to check this.

I looked at various questions here and the questions were filled out on github, but it is not clear to me what official way to deal with this situation. I don't think I'm dealing with a weird scenario ...

EDIT

My arctature is a fragment containing a presenter containing a DataStore.

I found a very long process, so I moved it to a separate thread, as it is on the presenter

Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        // Events is a collection of DTOs, they are not Realm objects (converted from Realm object to DTO inside dataStore)
        events = dataStore.getEvents(filterTerm);

        view.getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (events.size() > 0) {
                    view.showEvents(events);
                }
            }
        });
    }
});

thread.start();

EDIT

Adding 3 queries executed per line. They are called from 3 different methods.

Request 1

final RealmResults<Event> results = query.findAllAsync();
results.addChangeListener(new RealmChangeListener() {
    @Override
    public void onChange() {
        ....
    }
});

Request 2

final RealmResults<T> result = realm.where(type).findAllAsync();
result.addChangeListener(new RealmChangeListener() {
    @Override
    public void onChange() {
        ...
    }
});

Request 3

final RealmResults<PresentationSpeaker> results = query.findAllAsync();
results.addChangeListener(new RealmChangeListener() {
    @Override
    public void onChange() {
        ...
    }
});
+4
source share
1 answer

, DataStore , , : , postRunnable. DataStore, , . , Datastore , - , RxJava. API Realms (https://realm.io/docs/java/latest/#asynchronous-queries), :

// DataStore
public class DataStore {

   private final Realm realm;

   public DataStore() {
     realm = Realm.getDefaultInstance(); // Called on the UI thread
   }

    public void getEvents(EventsLoadedListener listener) {
      RealmResults<Event> results = realm.where(Events.class).findAllAsync();
      results.addChangeListener(new RealmChangeListener() {
        public void onChange() {
          if (listener != null) {
            listener.eventsLoaded(results);
          }
        }
      });
    }

    public interface EventsLoadedListener {
      public void eventsLoaded(List<Event> events);
    }

}

// UI code
datastore.getEvents(new DataStore.EventsLoadedListener() {
    public void eventsLoaded(List<Event> events) {
      view.showEvents(events);
    }
})

RxJava, , . Realm RxJava : https://realm.io/docs/java/latest/#rxjava

+3

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


All Articles