【问题标题】:Realm access across threads with rxjava and dagger2使用 rxjava 和 dagger2 跨线程访问领域
【发布时间】:2016-09-02 01:44:50
【问题描述】:

我已经阅读了很多关于这个主题的帖子,但对我来说还是有点不清楚。我知道您无法跨不同线程访问 Realm 类或领域对象,所以我想知道处理它的最佳方法是什么。

我有一个启动线程的服务。该线程进行后台工作(包括通过Schedulers.io 上的rxjava 工作)。现在在某个时刻,我想将一些数据保存到 DataManager 类中的领域。最初我使用Dagger2Realm 注入我的DataManager 类(它本身已注入服务)。但是这不起作用,因为注入是在主线程上完成的,所以 Realm.getDefaultInstance() 绑定到主线程,但它是在 DataManager 中从不同的线程访问的。

我能想到的唯一可行的选择是在执行事务的每个方法的开头和结尾调用Realm.getDefaultInstance()realm.close()。我不介意这样做,但我想知道每次我想保存对象时调用Realm.getDefaultInstance() 是否会对性能造成影响。有一个更好的方法吗?提前致谢。

【问题讨论】:

  • Realm.getDefaultInstance() 如果是所有线程中的第一个实例,会有点慢。否则,它会立即返回,因为 Realm 在内部缓存模式。见github.com/realm/realm-java/issues/2231
  • 仅供参考,我决定为我的特定用例放弃 Realm。我基本上需要对所有获取的对象执行copyFromRealm,这样我就可以跨线程传递它们,然后活动对象的好处就几乎没有了。它也是管理助手类中关闭领域实例的一种方式。我确信有更好的方法来处理这个问题,但我决定坚持使用 sqlite 和 orm。

标签: java android multithreading realm


【解决方案1】:

我在我的一个应用程序中使用 Realm 时解决了线程问题,方法是创建一个 DatabaseManager 类,我使用 Dagger 2 将其注入到活动和服务中。

例如,如果我有一个实体TaskDatabaseManager 类有一个方法void update(Task task),它将获取默认的 Realm 实例,从 Realm 数据库中获取具有给定 ID 的 Task,更新获得的Task 实例在 Transaction 块中,执行 realm.copyFromRealm(updatedTask); 并在方法结束时关闭 Realm 实例。

Realm realm = Realm.getDefaultInstance();
        realm.executeTransaction(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                // fetch the object from Realm database and update it as required.

                //https://realm.io/docs/java/latest/api/io/realm/Realm.html#copyFromRealm-E-
                // Makes an unmanaged in-memory copy of an already persisted RealmObject.
                realm.copyFromRealm(task);

                }
            }
        });
realm.close();

它对我有用。如果有更好的方法,我想了解更多。

【讨论】:

    猜你喜欢
    • 2017-03-22
    • 2022-01-17
    • 1970-01-01
    • 2017-09-23
    • 1970-01-01
    • 2017-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多