我正在开发一个Android应用程序,它在服务中接收一些BLE数据,然后将它们存储到Realm
数据库,并显然显示在Activities
和Fragments
上。
我设置了一个名为Singleton
的{{1}}类,它使用单个RealmManager
实例(使用getDefaultInstance)来执行事务和查询。
如果我调用Realm
方法将新数据存储到RealmManager
,则会触发异常,因为我在不同的线程上使用Realm。在此示例中,我无法从服务和活动中调用Realm
:
RealmManager.sharedInstance().userWithEmail("pippo")
如果我在每个方法上实例化一个新的public class RealmManager {
private static Realm realmDB;
private static RealmManager ourInstance;
public RealmManager(){
realmDB = Realm.getDefaultInstance();
}
public static RealmManager sharedInstance(){
if(ourInstance == null)
ourInstance = new RealmManager();
}
public User userWithEmail(String email){
User user = realmDB.where(User.class).equalTo(USER_EMAIL, email).findFirst();
return user;
}
}
实例,然后在最后调用Realm
,我就不能在应用程序中使用realm结果,因为Realm.close
实例已经关闭。
在此示例中,我无法在调用者中使用Realm
,因为实例已经关闭:
user
如何让RealmManager类从应用程序和服务中保存和检索所有应用程序的数据库数据?
答案 0 :(得分:1)
你不能像这样创建一个单独的领域。
通常你需要private static class RefAndCount {
// The global Realm instance in this thread.
private final ThreadLocal<BaseRealm> localRealm = new ThreadLocal<>();
// How many local references to this Realm instance in this thread.
private final ThreadLocal<Integer> localCount = new ThreadLocal<>();
// How many threads have instances refer to this configuration.
private int globalCount = 0;
}
private synchronized <E extends BaseRealm> E doCreateRealmOrGetFromCache(RealmConfiguration configuration) {
RefAndCount refAndCount = refAndCountMap.get(RealmCacheType.valueOf(Realm.class));
if (refAndCount.localRealm.get() == null) {
// Creates a new local Realm instance
BaseRealm realm = Realm.createInstance(this);
refAndCount.localRealm.set(realm);
refAndCount.localCount.set(0);
refAndCount.globalCount++;
}
Integer refCount = refAndCount.localCount.get();
refAndCount.localCount.set(refCount + 1);
//noinspection unchecked
return (E) refAndCount.localRealm.get();
}
synchronized void release(BaseRealm realm) {
String canonicalPath = realm.getPath();
RefAndCount refAndCount = refAndCountMap.get(RealmCacheType.valueOf(Realm.class));
Integer refCount = refAndCount.localCount.get();
if (refCount == null) {
refCount = 0;
}
if (refCount <= 0) {
RealmLog.warn("%s has been closed already. refCount is %s", canonicalPath, refCount);
return;
}
refCount -= 1;
if (refCount == 0) {
refAndCount.localCount.set(null);
refAndCount.localRealm.set(null);
refAndCount.globalCount--;
if (refAndCount.globalCount < 0) {
// Should never happen.
throw new IllegalStateException("Global reference counter of Realm" + canonicalPath + " got corrupted.");
}
realm.doClose();
if (getTotalGlobalRefCount() == 0) {
configuration = null;
}
} else {
refAndCount.localCount.set(refCount);
}
}
,但是Realm已经使用所谓的RealmCache
在内部管理它,看起来有点像这样:
Realm.getDefaultInstance()
考虑到这一点,我们学到的是:
1。)localCount 0 -> 1
增加本地计数,并打开一个新的全局线程本地Realm实例
如果realm.close()
2。)localCount 1 -> 0
减少本地计数
3。)如果synchronized
,则释放全局线程本地Realm实例
4.)所有这些方法在实现中都是{{1}}
考虑到这一点,您可能不应该为所有线程创建全局Realm实例。主要是因为您将在现有的线程本地缓存之上创建线程本地缓存,并且它变得棘手。虽然您可以查看this question as an example from daniel christopher(gist)。
通常,您应该提供本地Realm实例并关闭它们。
documentation describes the best practices for managing Realm instance lifecycle,虽然我个人更喜欢每个帖子只保留1个Realm实例。