Updating multiple instances of Realm at once?

I use a setup in which each Presenter , which is a saved Fragment , has its own instance of Realm . However, this essentially means that these Realms are in the main thread.

Now it also means that if I want to change Realm, I either have to do this in the main thread (which is good for small datasets, but I really don't want to do this with large datasets), or I need to do this in the background thread and update each Realm instance immediately (which is possible using a simple event for the event bus).

 public enum SingletonBus { INSTANCE; private static String TAG = SingletonBus.class.getSimpleName(); private Bus bus; private boolean paused; private final Vector<Object> eventQueueBuffer = new Vector<>(); private Handler handler = new Handler(Looper.getMainLooper()); private SingletonBus() { this.bus = new Bus(ThreadEnforcer.ANY); } public <T> void postToSameThread(final T event) { bus.post(event); } public <T> void postToMainThread(final T event) { try { if(paused) { eventQueueBuffer.add(event); } else { handler.post(new Runnable() { @Override public void run() { try { bus.post(event); } catch(Exception e) { Log.e(TAG, "POST TO MAIN THREAD: BUS LEVEL"); throw e; } } }); } } catch(Exception e) { Log.e(TAG, "POST TO MAIN THREAD: HANDLER LEVEL"); throw e; } } public <T> void register(T subscriber) { bus.register(subscriber); } public <T> void unregister(T subscriber) { bus.unregister(subscriber); } public boolean isPaused() { return paused; } public void setPaused(boolean paused) { this.paused = paused; if(!paused) { Iterator<Object> eventIterator = eventQueueBuffer.iterator(); while(eventIterator.hasNext()) { Object event = eventIterator.next(); postToMainThread(event); eventIterator.remove(); } } } } 

and

 SingletonBus.INSTANCE.postToMainThread(new RealmRefreshEvent()); @Subscribe public void onRealmRefreshEvent(RealmRefreshEvent e) { this.realm.refresh(); } 

But assuming that about 5-7 real-world instances are open in the main stream (since each presenter has his own area until they are destroyed), I am concerned about the performance and / or use of memory.

So, I have two questions:

1.) Is it bad practice / resource intensive to have multiple instances of Realm open in the main thread?

2.) How resource-intensive is updating multiple Realms in the same thread with the global refresh event?

+2
source share
2 answers

Realm uses ThreadLocal cache inside pr. Realm, so you can actually call Realm.getInstance() in every action / fragment / presenter that you have. The first call to Realm.getInstance() will cost a little, because the database must be open and the schema checked, but after that it will simply cost to find the cache.

The cache refers to the link, so the source resources will only be released after all instances are closed. This means that it is useful to maintain at least one open instance for as long as possible.

This also means that when you upgrade 1 from open instances, they all update automatically.

+2
source

A possible way to have open space at any time while the application is active.

 public class BaseActivity extends AppCompatActivity { private CustomApplication customApplication; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); customApplication = (CustomApplication)getApplication(); if(savedInstanceState == null) { customApplication.incrementActivityCounter(); } } @Override protected void onDestroy() { if(isFinishing()) { customApplication.decrementActivityCounter(); } super.onDestroy(); } } public class CustomApplication extends Application { public static final String TAG = CustomApplication.class.getSimpleName(); private volatile int activityCounter = 0; private Realm realm; @Override public void onCreate() { super.onCreate(); Log.d(TAG, "Application onCreate() called."); initializeRealm(); } public void incrementActivityCounter() { if (activityCounter == 0) { Log.d(TAG, "Increment: Activity counter was 0, initializing Realm."); if(realm == null) { initializeRealm(); } } activityCounter++; Log.d(TAG, "Increment: Activity counter incremented to " + activityCounter + "."); } public void decrementActivityCounter() { activityCounter--; Log.d(TAG, "Decrement: Activity counter decremented to " + activityCounter + "."); if(activityCounter == 0) { realm.close(); realm = null; Log.d(TAG, "Decrement: Activity counter was 0, closed realm."); } } private void initializeRealm() { realm = Realm.getInstance(this); Log.d(TAG, "Realm initialized."); } public Realm getRealm() { return realm; } public int getActivityCounter() { return activityCounter; } public void setActivityCounter(int activityCounter) { this.activityCounter = activityCounter; //process death } } 

And then

 public class BaseActivity extends AppCompatActivity { @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt("activityCounter", ((CustomApplication) getApplication()).getActivityCounter()); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); int activityCounter = savedInstanceState.getInt("activityCounter"); ((CustomApplication) getApplication()).setActivityCounter(activityCounter); //fix process death initializing activity counter to 0 Log.d(TAG, "Reset activity counter in application after process death to [" + activityCounter + "]"); } } 
+2
source

All Articles