private ConcurrentLinkedQueue<RealmRunnable> runnableConcurrentLinkedQueue = new ConcurrentLinkedQueue<>();
private Thread realmThread;
realmThread = new Thread(new Runnable() {
Realm realm;
@Override
public void run() {
while (!realmThread.isInterrupted()) {
if (runnableConcurrentLinkedQueue.isEmpty()) {
synchronized (realmThreadLock) {
if (runnableConcurrentLinkedQueue.isEmpty()) {
与序列化可运行执行管理相关的所有操作都可以用一行代码完成:
Executor singleThreadedExecutor = Executors.newSingleThreadedPool();
然而,这将假设每当您发布runnable时,您需要打开/关闭领域。
singleThreadedExecutor.post(new Runnable() {
@Override public void run() {
try {
realmManager.openLocalInstance();
// do whatever
} finally {
realmManager.closeLocalInstance();
}
}
});
如果realm是现成的,这当然也可以:
singleThreadedExecutor.post(new Runnable() {
@Override public void run() {
try(Realm realm = Realm.getDefaultInstance()) {
// do whatever, but you have to pass Realm around instead of `getLocalInstance()`
}
// realm is closed here
}
});
如果您希望每个可运行的自动生命周期管理,以便域使用
realmManager.getLocalInstance()
在后台线程上,不需要自己手动打开它,那么您需要更深入。请注意,我是第一次在这里写这篇文章,所以在这方面有点理论性。
不管怎样,你需要扩展
ThreadPoolExecutor
并定义
protected void beforeExecute(Thread t, Runnable r)
和
protected void after(Thread t, Runnable r)
是的。它看起来像这样:
public class RealmThreadPoolExecutor extends ThreadPoolExecutor {
private final RealmManager realmManager;
public RealmThreadPoolExecutor(RealmManager realmManager) {
super(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); // from newSingleThreadedPool
this.realmManager = realmManager;
}
@Override protected void beforeExecute(Thread thread, Runnable runnable) {
super.beforeExecute(thread, runnable);
realmManager.openLocalInstance();
realmManager.getLocalInstance().refresh();
}
@Override protected void afterExecute(Thread thread, Runnable runnable) {
super.afterExecute(thread, runnable);
realmManager.closeLocalInstance();
}
}
然后,您将执行以下操作,而不是您亲自管理的可运行执行:
private final Executor realmExecutor = new RealmThreadPoolExecutor(realmManager);
public void addRunnable(Runnable runnable) {
realmExecutor.execute(runnable);
}
它应该和你做的一样。除了代替
RealmRunnable
和
setRealm
,你会打电话给
realmanager.getLocalInstance()
是的。
顺便说一句,
get
不应该打开一个领域,如果你需要在那里打开一个领域,那么这意味着生命周期管理是错误的,你应该已经打开它之前,所以它只是隐藏错误。
严格地说你
也
选择使用君主制而不是使用您自己的手动线程本地缓存(虽然我个人不确定您是否同时需要这两个…),这意味着您将以“单一方式”使用realm,只需在
monarchy.doWithRealm(new RealmBlock() {
是的。
@Override public void run() {
monarchy.doWithRealm((realm) -> {
// realm is open here
});
// realm is closed here
}
君主制不会暴露
open/close
直接因为人们
永不关闭王国
(我知道,我在这里已经有一段时间了)所以这个街区不允许他们这么做。除非他们手动呼叫
Realm.getDefaultInstance()
在某些地方,君主制会在不需要的时候关闭王国。这个
利益
如果您想要交易,请执行以下操作:
monarchy.runTransactionSync((realm) -> {
// do transaction. Realm is opened by config automatically.
});
// realm is closed here.
最重要的是,通过君主制,ui线程查询都通过livedata公开,其中至少有一个订阅者打开领域,而有0个订阅者关闭领域——因此在ui线程上,领域生命周期由您对领域查询的订阅自动管理。如果没有观察者,那么领域是关闭的。
LiveData<List<RealmDog>> dogs;
Observer<List<RealmDog>> observer = dogs -> {
adapter.updateData(dogs);
};
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ButterKnife.bind(this, view);
...
dogs = monarchy.findAllCopiedWithChanges(realm -> realm.where(RealmDog.class));
dogs.observeForever(observer);
}
@Override
public void onDestroyView() {
dogs.removeObserver(observer);
super.onDestroyView();
}
不管你选择哪条路,你都应该删除它
RealmController
,你不需要它。