2016-07-06 174 views
1

这个问题查询境界的数据是从一个后续问题:Organize Android Realm data in lists包含的其他对象

由于我们使用的API返回的数据,这是略不可能的境界数据库上做一个实际的查询。相反,我正在将我的订购数据包装在RealmList中,并向其中添加@PrimaryKey public String id;

因此,我们的境界的数据是这样的:

public class ListPhoto extends RealmObject { 
    @PrimaryKey public String id; 
    public RealmList<Photo> list; // Photo contains String/int/boolean 
} 

这使得简单地使用API​​端点作为id容易写入和境界DB读取。

所以它典型的查询是这样的:

realm.where(ListPhoto.class).equalTo("id", id).findFirstAsync(); 

这将创建一个稍微开销listening/subscribing数据,因为现在我需要检查listUser.isLoaded()使用ListUseraddChangeListener/removeChangeListenerListUser.list我的适配器上的实际数据。

所以我的问题是:

有没有一种方法,我可以查询这个境界接收RealmResults<Photo>。这样我可以很容易地在RealmRecyclerViewAdapter中使用这些数据,并直接在其上使用监听器。

编辑:为了进一步澄清,我想像下面的东西(我知道这不会编译,它只是我想实现的伪代码)。

realm 
.where(ListPhoto.class) 
     .equalTo("id", id) 
     .findFirstAsync() // get a results of that photo list 
.where(Photo.class) 
     .getField("list") 
     .findAllAsync(); // get the field "list" into a `RealmResults<Photo>` 

编辑最终代码:考虑到它是不可能的ATM直接做的查询,我的最终解决方案是简单地有检查数据适配器,如果需要订阅。代码如下:

public abstract class RealmAdapter 
        <T extends RealmModel, 
         VH extends RecyclerView.ViewHolder> 
      extends RealmRecyclerViewAdapter<T, VH> 
      implements RealmChangeListener<RealmModel> { 

    public RealmAdapter(Context context, OrderedRealmCollection data, RealmObject realmObject) { 
     super(context, data, true); 
     if (data == null) { 
     realmObject.addChangeListener(this); 
     } 
    } 

    @Override public void onChange(RealmModel element) { 

     RealmList list = null; 
     try { 
     // accessing the `getter` from the generated class 
     // because it can be list of Photo, User, Album, Comment, etc 
     // but the field name will always be `list` so the generated will always be realmGet$list 
     list = (RealmList) element.getClass().getMethod("realmGet$list").invoke(element); 
     } catch (Exception e) { 
     e.printStackTrace(); 
     } 

     if (list != null) { 
     ((RealmObject) element).removeChangeListener(this); 
     updateData(list); 
     } 
    } 
} 
+0

*有没有办法*您要查询什么我可以查询这个境界? 'realm.where(ListPhoto.class).equalTo(“id”,id).findFirstAsync();''的结果。 –

+0

@TimCastelijns是的。我想一个'RealmResults '(甚至直接的'RealmList'),将匹配'RealmList '了'ListPhoto'内。我知道我可以通过同步呼叫来完成。但我真的更喜欢使用异步。 – Budius

+0

我用一些伪代码编辑了这个问题。我希望更清楚 – Budius

回答

1

首先你查询ListPhoto,因为它是异步的,你必须注册一个监听器的结果。然后在该监听器中,您可以查询结果以获取RealmResult。

像这样的事情

final ListPhoto listPhoto = realm.where(ListPhoto.class).equalTo("id", id).findFirstAsync(); 
listPhoto.addChangeListener(new RealmChangeListener<RealmModel>() { 
    @Override 
    public void onChange(RealmModel element) { 
     RealmResults<Photo> photos = listPhoto.getList().where().findAll(); 
     // do stuff with your photo results here. 


     // unregister the listener. 
     listPhoto.removeChangeListeners(); 
    } 
}); 

注意,你实际上可以查询RealmList。这就是为什么我们可以拨打listPhoto.getList().where()where()只是意味着“全部返回”。

我无法测试它,因为我没有你的代码。您可能需要使用((ListPhoto) element)来投射element

+0

谢谢蒂姆。我担心这是唯一的答案。像这样,我不能直接在'onCreate'期间生成RealmResult(或List),而必须等待回调。 – Budius

+0

@Budius如果你使用异步查询,是的,那么你必须等待回调:-) –

+0

@Budius我曾希望你在活动或任何地方做查询,并传递'RealmResults photos = listPhoto的结果。 getList()。where()。findAll();'到适配器而不是在适配器内查询 –

1

我知道你说你不考虑使用同步API的选项,但我仍然认为这是值得一提的是,您的问题将得到解决,像这样:

RealmResults<Photo> results = realm.where(ListPhoto.class).equalTo("id", id).findFirst() 
          .getList().where().findAll(); 

编辑:要完全信息,虽然,我举docs

findFirstAsync

公共电子findFirstAsync()

类似的FindFirst(),但在异步工作线程运行时,此方法只能从弯针线。

返回:立即空RealmObject。

试图访问返回的对象在任何领域中,加载 之前将抛出IllegalStateException。

使用RealmObject.isLoaded(),以检查是否对象被完全加载

或注册监听RealmObject.addChangeListener(io.realm.RealmChangeListener<E>)是 的查询完成时通知。

如果是 查询结束后没有发现RealmObject,返回RealmObject将有 RealmObject.isLoaded()设置为true,RealmObject.isValid()设置为 假。

所以在技术上,是的,你需要做到以下几点:

private OrderedRealmCollection<Photo> photos = null; 
//... 

final ListPhoto listPhoto = realm.where(ListPhoto.class).equalTo("id", id).findFirstAsync(); 
listPhoto.addChangeListener(new RealmChangeListener<ListPhoto>() { 
    @Override 
    public void onChange(ListPhoto element) { 
     if(element.isValid()) { 
      realmRecyclerViewAdapter.updateData(element.list); 
     } 
     listPhoto.removeChangeListeners(); 
    } 
} 
+0

你能解释这将如何不同于直接使用像这样的列表:'realm.where(ListPhoto.class).equalTo(“id”,id).findFirst()。getList()'我的意思是,如果列表已经存在了,我不需要第二个查询,我可以直接使用'RealmList '对象。没有? – Budius

+0

技术上来说,是因为我认为0.89.0和'OrderedRealmCollection ''介绍的介绍,但你说你想要一个'RealmResults ',并且这将列表转换为结果。但是这只是让你的'list'被视为一个'view',它实际上并没有花费任何东西来做'.where()。findAll()'转换。 – EpicPandaForce

+0

我想要'RealmResult',因为这个想法是能够从查询中获得整个异步的。如果要同步执行,我将直接使用'RealmList'。非常感谢答复和评论。我需要一些时间来平衡方法之间的利弊,但它非常有见地。我希望我可以将两者都标为正确。 – Budius

相关问题