【问题标题】:RealmResult as RealmObject fieldRealmResult 作为 RealmObject 字段
【发布时间】:2017-06-02 05:32:59
【问题描述】:

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

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

Goal 包含此 RealmResult 成就的最佳方式是什么?以下是我想到的一些方法:

  1. 在 Goal 中有一个持久化的 RealmList 字段,并在更改会更改结果查询的字段时对其进行更新。但是,如果将新的成就添加到领域,该 RealmList 将如何更新?
  2. 在目标内的RealmResult<Achievement> 字段上使用@Ignore 注释。在目标中使用 mResult 的任何地方,首先检查是否为空,如果需要,重新查询。如果我使用 RecyclerView 之类的东西重新获取getItem() 中的对象,这似乎我会做很多不必要的查询。
  3. 拥有一个包含 Goal 对象和 RealmResult<Achievement> 作为字段的包装类。向 Goal 添加一个侦听器,以便在相关字段更改时可以重新查询 RealmResult。

我倾向于最后一个作为保持有效 RealmResult 的最干净的方式。我是否错过了一种更简单的方法来实现这一点?

【问题讨论】:

  • 让我想起了this idea,但它在“想法积压”中,所以不会很快发生。
  • 谢谢@EpicPandaForce!假设我们不会很快得到@Query,你知道实现这一目标的最佳方法是什么吗?
  • 就我个人而言,我可能只是有一个类似于 RealmResults<Achievement> achievements = achievementDao.findForGoal(realm, goalId);... 的抽象...但这只是我。

标签: android realm


【解决方案1】:

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

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...
    }
}

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

我担心的一个问题是我从不删除 mGoal 上的侦听器。我什至需要删除它吗?在 ArrayList 被 GC 处理的情况下会发生什么?我认为 Goal 字段和附加到它的结果侦听器也会被 GC 处理。

【讨论】:

  • 如果您只在调用 realmResults.get(i) 时创建 GoalWrapper,这意味着在 onBindViewHolder() 中,那么您将保持惰性求值,而不必将所有目标保存在 ArrayList 中。
  • 这不是每次都必须重新运行 findResultForGoal 的成本,而不是在首次查询目标时一次吗?未显示 calculateStats 实现,但它也必须遍历结果中的每个成就。
  • 好吧那是真的......根据元素的数量,太多的findAll()调用可能会导致速度变慢。 ArrayList 也可以,是的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多