如何正确管理 Android 中的 Realm ,以确保所有数据库实例最终关闭,但保持打开状态足够长的时间,以便查看 DataBind 托管对象并观察更改?
我想知道与 Realm 实例交互时是否有最佳实践,以确保可以观察数据,同时确保对数据库的每个引用都正确关闭。我一直在寻找解决这个问题的好方法,但到目前为止,它似乎要么是 Realm 的一个主要下降点,要么是一个保守的 secret 。在之前的项目中,我在与数据库交互时没有正确关闭 Realm 实例,这最终导致了巨大的麻烦和进一步的重构。
我正在开始一个新项目,并希望确保从一开始就正确设置了所有内容。我正在开发的应用程序将收到推送通知,这些通知将触发服务器的更新并将更改存储在数据库中。我想用 Realm 观察数据库中的相关数据,以便数据绑定(bind) View 可以在数据库更改时自动更新。如果我错了,请纠正我,但我的理解是,要观察数据库,从中获取数据的 Realm 实例必须保持打开状态。这意味着我无法使用单个存储库来打开新的 Realm 实例、获取我需要的模型,然后将其传回,因为我将无法观察更改。
我提出的解决方案是创建一个存储库层,其中包含 3 种与数据库交互的方式。这三个选项是复制、更新和收听。复制和更新函数将在单个 block 中打开和关闭 Realm 实例,如下所示:
public RealmObject copyOrUpdate() {
Realm realm = Realm.getDefaultInstance()
try {
// Transaction
} finally {
realm.close()
}
}
但是,当我需要观察模型时,我无法使用它,因为数据库将在观察 View 被销毁之前关闭。因此,为了跟踪 Realm 实例,当我创建每个需要可观察的 ViewModel 时,我将打开一个新实例。然后,当我需要托管对象时,我将传递 Realm 实例:
public RealmObject observeObject(Realm realm) {
return // Managed object
}
最后当View被销毁并且ViewModel被清除时关闭Realm实例。根据我目前对 Realm 的理解,老实说,我想不出另一种或更好的方法来做到这一点,并且通过在线阅读,除了这篇未得到解答的帖子之外,我找不到其他人有相同或类似的问题:
How to properly separate Realm from the rest of the app?
任何帮助、见解或建议将不胜感激,以便我可以提高对 Realm 的理解并避免进一步的麻烦。
我还想知道观察 Realm 数据库的最佳方法,因为 Realm 似乎不提供对 LiveData 的支持,并且注册/取消注册 RealmChangeListeners 似乎是一个即将发生的事故。是否有官方支持的处理 LiveData 的方法,或者我需要学习如何正确使用 RealmChangeListeners?最后,我过去使用 Room 取得了很多成功,并且觉得它是一个更好的解决方案,因为它作为 Android 架构组件得到了正式支持。我看到辩论双方都有人,但有什么具体原因我应该远离 Room 吗?
预先感谢您的任何帮助或指导。
最佳答案
Realm 没有好的文档,但我可以与您分享我的经验:
您可以使用如下所示的所有交易:
/** * insert or update your model in data base * @param basemodel what u want to insert */ public void insertOrUpdate(RealmModel basemodel){ try { realm = Realm.getDefaultInstance(); realm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { realm.insertOrUpdate(basemodel); } }); } finally { if(realm != null) { realm.close(); } }
}
在类里面可以看到这个:
public class MyRealm {
Realm realm = null;
public RealmModel results = new RealmModel();
Context context;//optional
因此您可以为 Realm 作业构建一个类,用于插入和更新或删除和读取以及您想要从 Realm 中获得的任何内容
2.realm中的配置太重要了,你必须创建一个类并从应用程序类扩展,如下所示:
public class MyApplication extends Application {
byte[] key = new byte[64];
private byte[] createRealmKey() {
byte[] key = new byte[64];
SecureRandom secureRandom = new SecureRandom();
secureRandom.nextBytes(key);
return key;
}
@Override
public void onCreate() {
super.onCreate();
if (key == null) {
key=createRealmKey();
}
Realm.init(this);
RealmConfiguration config = new RealmConfiguration.Builder()
.name("name.realm")
.schemaVersion(1)
.encryptionKey(key)
.deleteRealmIfMigrationNeeded()
.build();
Realm.setDefaultConfiguration(config);
}
这是对您有用的加密数据和 schemaVersions 的 Realm 配置。
现在你的答案就在这里: 如果你以正确的方式使用类和 RealmModel,你可以使用数据绑定(bind)和 rx 等所有东西
查看此职位:
RealmModel baseRealmModel = new new RealmModel();
baseRealmModel = myRealm.realmQueryOfRealmModel();//return a
////realm object for you that can do all with it
baseRealmModel.setUser(realmUser);
myRealm.insertOrUpdate(baseRealmModel);
您可以在评论中提出更多问题
关于java - 如何正确管理Android中的 Realm 以数据绑定(bind) View ,但关闭所有 Realm 实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59307454/