使用 rxjava 和 dagger2 跨线程访问领域
Posted
技术标签:
【中文标题】使用 rxjava 和 dagger2 跨线程访问领域【英文标题】:Realm access across threads with rxjava and dagger2 【发布时间】:2016-09-02 01:44:50 【问题描述】:我已经阅读了很多关于这个主题的帖子,但对我来说还是有点不清楚。我知道您无法跨不同线程访问 Realm
类或领域对象,所以我想知道处理它的最佳方法是什么。
我有一个启动线程的服务。该线程进行后台工作(包括通过Schedulers.io
上的rxjava
工作)。现在在某个时刻,我想将一些数据保存到 DataManager 类中的领域。最初我使用Dagger2
将Realm
注入我的DataManager 类(它本身已注入服务)。但是这不起作用,因为注入是在主线程上完成的,所以 Realm.getDefaultInstance()
绑定到主线程,但它是在 DataManager 中从不同的线程访问的。
我能想到的唯一可行的选择是在执行事务的每个方法的开头和结尾调用Realm.getDefaultInstance()
和realm.close()
。我不介意这样做,但我想知道每次我想保存对象时调用Realm.getDefaultInstance()
是否会对性能造成影响。有一个更好的方法吗?提前致谢。
【问题讨论】:
Realm.getDefaultInstance()
如果是所有线程中的第一个实例,会有点慢。否则,它会立即返回,因为 Realm 在内部缓存模式。见github.com/realm/realm-java/issues/2231
仅供参考,我决定为我的特定用例放弃 Realm。我基本上需要对所有获取的对象执行copyFromRealm
,这样我就可以跨线程传递它们,然后活动对象的好处就几乎没有了。它也是管理助手类中关闭领域实例的一种方式。我确信有更好的方法来处理这个问题,但我决定坚持使用 sqlite 和 orm。
【参考方案1】:
我在我的一个应用程序中使用 Realm 时解决了线程问题,方法是创建一个 DatabaseManager
类,我使用 Dagger 2 将其注入到活动和服务中。
例如,如果我有一个实体Task
,DatabaseManager
类有一个方法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();
它对我有用。如果有更好的方法,我想了解更多。
【讨论】:
以上是关于使用 rxjava 和 dagger2 跨线程访问领域的主要内容,如果未能解决你的问题,请参考以下文章
Android实现文章+评论(MVP,RxJava,Dagger2,ButterKnife)
Android--带你一点点封装项目 MVP+BaseActivity+Retrofit+Dagger+RxJava
[Android] 转-RxJava+MVP+Retrofit+Dagger2+Okhttp大杂烩
一款最流行的MVPArms MVP快速集成框架Retoift,Okhttp,RxCache,Gson,RxLifeCycle, Dagger2,Rxjava,ImageLoader
一套整合主流HTTP网络图片加载MVP(RxJava2+Dagger2)架构的快速高效的开发框架RxEasyAndroid
一套整合主流HTTP网络图片加载MVP(RxJava2+Dagger2)架构的快速高效的开发框架RxEasyAndroid