RealmResult作为RealmObject字段

时间:2017-06-01 09:02:41

标签: android realm

我正在尝试找出将RealmResult作为其字段之一来设置RealmObject的最佳方法。

例如,假设我有两个RealmObject,GoalAchievement。目标对象包含定义用户想要跟踪的成就查询的字段(例如,创建成就的日期范围,成就类型等),并具有从这些成就中提取统计数据的自定义方法。

目标包含此RealmResult of Achievements的最佳方法是什么?以下是我想到的一些方法:

  1. 在目标中有一个持久的RealmList字段,并在更改字段时更新它,这将更改生成的查询。但是,如果新的成就被添加到领域,这个RealmList将如何更新?
  2. 在目标中的@Ignore字段上使用RealmResult<Achievement>注释。在使用mResult的目标中的任何位置,首先检查是否为null并在需要时重新查询。如果我使用像RecyclerView这样的东西来重新获取getItem()中的对象,我似乎会做很多不必要的查询。
  3. 有一个包含Goal对象且RealmResult<Achievement>为字段的包装类。添加一个侦听器到目标,以便任何时候相关字段更改可以重新获取RealmResult。
  4. 我倾向于最后一个作为保持有效RealmResult最干净的方法。我错过了一种更简单的方法来实现这个目标吗?

1 个答案:

答案 0 :(得分:0)

好的,所以我试图实现一个包装类(我认为类似于DAO抽象@EpicPandaForce提到的,但我并不十分熟悉它)

public class GoalWrapper {
    private RealmResults<Achievements> mResults;
    private Goal mGoal;
    private Realm mRealm;

    public GoalWrapper(Realm realm, Goal goal) {
        mRealm = realm;
        mGoal = goal;

        // TODO: does this need to be removed somewhere?  What happens when GoalWrapper gets GC'd?
        goal.addChangeListener(new RealmChangeListener<RealmModel>() {
            @Override
            public void onChange(RealmModel element) {
                // rerun the query
                findResultForGoal();
            }
        });

        findResultForGoal();
    }

    /**
     * Run a query for the given goal and calculate the result
     */
    private void findResultForGoal() {
        mResults = mRealm.where(Achievement.class)
                .greaterThanOrEqualTo("date", mGoal.getStartDate())
                .lessThanOrEqualTo("date", mGoal.getEndDate())
                .equalTo("type", mGoal.getAchievementType())
                .findAll();
        calculateStats();
    }

    private void calculateStats() {
        // Get relevant stats from mResult...
    }
}

我还没有测试过这段代码,但我计划让一个带有GoalWrapper对象ArrayList的RecyclerView.Adapter。

我唯一担心的是我永远不会删除mGoal上的监听器。我甚至需要将其删除吗?在ArrayList获得GC的情况下会发生什么?我认为目标字段和附属于它的结果听众都可以获得GC。