我正在我的应用程序中使用回收站视图,并希望在后台线程上进行一些计算,获取RealmObjects列表,并刷新我的适配器。
作为一个背景,我有一个非平凡的排序要求,并且recycleler视图需要显示由不同表上的查询产生的对象(尽管它们仍然产生相同的对象类型)。我不想在主线程上做这些可能很昂贵的查询。
最好的方法是什么? AFAIK,我可以
从后台线程获取ids(String)列表,并在主线程上进行查询。所以我会做realm.where(ObjectA.class).in(listOfIds).findAll()
之类的事情。但是,我不认为我保证集合的顺序是我的listOfIds的顺序,我在后台排序。然后我可以手动对领域集合进行排序。
或者,我可以做一个realm.copyFromRealm(listOfObjectA)
,假设我从后台线程中获得了一个对象列表。通过这种方式,我感觉更干净,但我显然失去了自动刷新功能,更不用说它将是内存密集型。似乎昂贵的复制将发生在主线程上,这会破坏我将事情转移到后台线程的努力。
我希望有一种方法可以让我将RealmResults或RealmList从一个线程转移到另一个线程。有人有关于如何做到这一点的建议吗?
答案 0 :(得分:4)
我有一个非常重要的排序要求
如果此排序完全基于您的RealmObject字段,则可以使用RealmQuery.findAllSortedAsync(...)
方法,该方法将在单独的工作线程上为您执行查询和排序。这是最好的选择。如果可能,您还可以分两个阶段进行排序,一个使用findAllSortedAsync
,另一个使用已经获得的对象的主线程 - 如果结果是按领域预先排序的话,第二个阶段可能不会那么昂贵。
并且recycleler视图需要显示由不同表上的查询产生的对象
您可以寻找在这些对象之间创建链接的可能性,例如,如果RealmObject A 有一个字段 b ,您可以对 A >进行排序strong>依据 b 字段 - 这可以解决您的问题,并将所有内容保存在一个领域查询中。
从后台线程获取id(String)列表,并在主线程上进行查询......
你是对的 - 不能保证在原始ID列表顺序中返回结果,所以这不是一个真正的选择。
或者,我可以做一个realm.copyFromRealm(listOfObjectA)......
这是正确的,但是你必须知道使用这种方法的限制和内存开销,即:
似乎昂贵的复制将发生在主线程上,这会破坏我将事情移入后台线程的努力。
实际上,如果您在线程 A 上执行copyFromRealm
并将列表传递给线程 B ,则会执行从域中硬拷贝的值通过主题 A ,所以没关系。
答案 1 :(得分:0)
你无法移动"生活"跨线程的RealmObjects,所以你已经列出的两个选项几乎就是你留下的。
如果你在后台线程上进行查询并使用copyFromRealm
创建断开连接的对象,对它们进行排序,然后将它们传递回主线程,这将全部发生在后台线程上,所以你&#39那里很好。
(小注意:如果您以与Realm中不同的格式显示数据,您还可以将其映射到更快的类,然后填充您的视图,而不是使用Realm中的Realm对象。 UI,因为您无论如何都丢失了同步功能。)
否则,如果您需要将它们连接到Realm,我认为您将不得不进行ID列表传输并承担在主线程上对它们进行排序的成本。
答案 2 :(得分:0)
使用copyFromRealm方法 在Java中:
MyRealmObject unManagedRealmObject= realmInstance.copyFromRealm(myRealmObject);
好吧,我们可以用更好的方法做到这一点:
var nonRealmObject: MyRealmObject?=null
set(value) { // here value is child of RealmObject
if (value!=null)
field = realmInstance.copyFromRealm(value) // converting RealmObject to unmanaged realm object
else
field=null
}
现在分配时:
nonRealmObject = someRealmObject // set(value) method will be called and it will convert realm to unmanaged realm object
注意:realmInstance
是已经创建的Realm的实例,如果您创建新的引用,请确保在完成工作后将其关闭。