如何跨线程传输RealmResults

时间:2017-03-07 20:38:30

标签: android realm

我正在我的应用程序中使用回收站视图,并希望在后台线程上进行一些计算,获取RealmObjects列表,并刷新我的适配器。

作为一个背景,我有一个非平凡的排序要求,并且recycleler视图需要显示由不同表上的查询产生的对象(尽管它们仍然产生相同的对象类型)。我不想在主线程上做这些可能很昂贵的查询。

最好的方法是什么? AFAIK,我可以

  1. 从后台线程获取ids(String)列表,并在主线程上进行查询。所以我会做realm.where(ObjectA.class).in(listOfIds).findAll()之类的事情。但是,我不认为我保证集合的顺序是我的listOfIds的顺序,我在后台排序。然后我可以手动对领域集合进行排序。

  2. 或者,我可以做一个realm.copyFromRealm(listOfObjectA),假设我从后台线程中获得了一个对象列表。通过这种方式,我感觉更干净,但我显然失去了自动刷新功能,更不用说它将是内存密集型。似乎昂贵的复制将发生在主线程上,这会破坏我将事情转移到后台线程的努力。

  3. 我希望有一种方法可以让我将RealmResults或RealmList从一个线程转移到另一个线程。有人有关于如何做到这一点的建议吗?

3 个答案:

答案 0 :(得分:4)

findAllSortedAsync

  

我有一个非常重要的排序要求

如果此排序完全基于您的RealmObject字段,则可以使用RealmQuery.findAllSortedAsync(...)方法,该方法将在单独的工作线程上为您执行查询排序。这是最好的选择。如果可能,您还可以分两个阶段进行排序,一个使用findAllSortedAsync,另一个使用已经获得的对象的主线程 - 如果结果是按领域预先排序的话,第二个阶段可能不会那么昂贵。

  

并且recycleler视图需要显示由不同表上的查询产生的对象

您可以寻找在这些对象之间创建链接的可能性,例如,如果RealmObject A 有一个字段 b ,您可以对 A 进行排序strong>依据 b 字段 - 这可以解决您的问题,并将所有内容保存在一个领域查询中。

重新查询已排序的ID(NO)

  

从后台线程获取id(String)列表,并在主线程上进行查询......

你是对的 - 不能保证在原始ID列表顺序中返回结果,所以这不是一个真正的选择。

copyFromRealm

  

或者,我可以做一个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的实例,如果您创建新的引用,请确保在完成工作后将其关闭。