java - 如何正确管理Android中的 Realm 以数据绑定(bind) View ,但关闭所有 Realm 实例?

标签 java android data-binding realm android-livedata

如何正确管理 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 没有好的文档,但我可以与您分享我的经验:

  1. 您可以使用如下所示的所有交易:

    /**
     * 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/

相关文章:

java - Spring @DependsOn 注释是否有 "revert"?

java - dataOutputStream.readFully 的进度

android - 启动谷歌地图以显示道路方向

java - Android APK 无法安装在设备上

c# - WPF 和 RibbonControlsLibrary 抛出 BindingExpression 路径错误,甚至不使用绑定(bind)?

C# MVVM : Binding a RadioButton to a boolean Property

java - 我一直收到 'No class was registered (through reference chain: ... )' ,但我注册了我的实体

java - 未找到 JSF 方法,而应该是

java - 如何在 Spring Data JPA 中执行嵌套连接获取

wpf - 当由于空值而无法评估绑定(bind)时,使用默认值