管理服务和应用程序之间的领域

时间:2017-05-31 10:40:53

标签: java android service android-service realm

我正在开发一个Android应用程序,它在服务中接收一些BLE数据,然后将它们存储到Realm数据库,并显然显示在ActivitiesFragments上。 我设置了一个名为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类从应用程序和服务中保存和检索所有应用程序的数据库数据?

1 个答案:

答案 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 christophergist)。

通常,您应该提供本地Realm实例并关闭它们。

documentation describes the best practices for managing Realm instance lifecycle,虽然我个人更喜欢每个帖子只保留1个Realm实例。