一次刷新多个 Realm 实例?
Refreshing multiple Realm instances at once?
我使用的设置中每个 Presenter
是保留的 Fragment
都有自己的 Realm
实例。然而,这本质上意味着这些Realms都在主线程上。
现在这也意味着,如果我想修改 Realm,我要么需要在主线程上这样做(这对于小数据集没问题,但我真的不想对大数据这样做集),或者我需要在后台线程上执行它,并立即刷新 every Realm 实例(这可以通过事件总线的简单事件实现)。
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();
}
}
}
}
和
SingletonBus.INSTANCE.postToMainThread(new RealmRefreshEvent());
@Subscribe
public void onRealmRefreshEvent(RealmRefreshEvent e) {
this.realm.refresh();
}
但假设我在主线程上打开了大约 5-7 个领域实例(因为每个演示者都有自己的开放领域,但它们没有被销毁),我担心性能 and/or 内存使用。
所以我想我有两个问题,
1.) 在 main 线程上打开多个 Realm 实例是不好的做法/资源密集型吗?
2.) 使用全局 refresh
事件在同一个线程上更新多个领域会占用多少资源?
Realm 在内部使用 ThreadLocal 缓存 pr。 Realm 文件,因此几乎可以在每个 activity/fragment/presenter 中免费调用 Realm.getInstance()
。第一次调用 Realm.getInstance()
会花费一些费用,因为必须打开数据库并验证模式,但之后只需花费一次缓存查找。
缓存是引用计数的,因此只有在关闭所有实例后才会释放本机资源。这意味着尽可能长时间地保留至少一个打开的实例是有益的。
这也意味着当您更新其中 1 个打开的实例时,它们都会自动更新。
一种在应用程序处于活动状态时始终拥有开放领域的可能方法。
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
}
}
然后
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 + "]");
}
}
我使用的设置中每个 Presenter
是保留的 Fragment
都有自己的 Realm
实例。然而,这本质上意味着这些Realms都在主线程上。
现在这也意味着,如果我想修改 Realm,我要么需要在主线程上这样做(这对于小数据集没问题,但我真的不想对大数据这样做集),或者我需要在后台线程上执行它,并立即刷新 every Realm 实例(这可以通过事件总线的简单事件实现)。
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();
}
}
}
}
和
SingletonBus.INSTANCE.postToMainThread(new RealmRefreshEvent());
@Subscribe
public void onRealmRefreshEvent(RealmRefreshEvent e) {
this.realm.refresh();
}
但假设我在主线程上打开了大约 5-7 个领域实例(因为每个演示者都有自己的开放领域,但它们没有被销毁),我担心性能 and/or 内存使用。
所以我想我有两个问题,
1.) 在 main 线程上打开多个 Realm 实例是不好的做法/资源密集型吗?
2.) 使用全局 refresh
事件在同一个线程上更新多个领域会占用多少资源?
Realm 在内部使用 ThreadLocal 缓存 pr。 Realm 文件,因此几乎可以在每个 activity/fragment/presenter 中免费调用 Realm.getInstance()
。第一次调用 Realm.getInstance()
会花费一些费用,因为必须打开数据库并验证模式,但之后只需花费一次缓存查找。
缓存是引用计数的,因此只有在关闭所有实例后才会释放本机资源。这意味着尽可能长时间地保留至少一个打开的实例是有益的。
这也意味着当您更新其中 1 个打开的实例时,它们都会自动更新。
一种在应用程序处于活动状态时始终拥有开放领域的可能方法。
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
}
}
然后
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 + "]");
}
}