2017-06-01 31 views
0

我想弄清楚設立RealmObject與RealmResult作爲其領域的最佳途徑之一。RealmResult作爲RealmObject場

例如,假設我有兩個RealmObjects,GoalAchievement。 Goal對象包含用於定義用戶想要跟蹤的Achievement的查詢的字段(例如創建成就的日期範圍,成就類型等),並具有從這些Achievements中提取統計信息的自定義方法。

什麼是目標包含成就的這RealmResult的最佳方式?這裏有一些我認爲是這樣做的方法:

  1. 在目標中有一個持久的RealmList字段,並在任何時候更新字段以更改結果查詢。但是如果一個新的成就被添加到領域,這個RealmList如何得到更新?
  2. 使用@Ignore註釋上的目標內的RealmResult<Achievement>場。在使用mResult的目標中的任何位置,首先檢查是否爲空,如果需要,則重新查詢。這看起來像我會做很多不必要的查詢,如果我正在使用像RecyclerView那樣重新繪製getItem()中的對象。
  3. 有一個包含目標對象和RealmResult<Achievement>作爲字段的包裝類。向Goal添加監聽器,以便隨時可以重新查詢相關字段更改RealmResult。

我傾向於最後一個,以保持一個有效的RealmResult最徹底的方法。我錯過了一個更簡單的方法來實現這一目標?

+1

讓我想起了[這個想法(https://github.com/realm/realm-java/issues/3210#issuecomment-234908853),但它的「主意積壓」,這樣就不會很快出現。 – EpicPandaForce

+0

謝謝,@EpicPandaForce!你知道什麼是最好的方法來實現這一點,假設我們沒有很快獲得@Query? – grantka

+1

就我個人而言,我可能只是有一個類似於'RealmResults 成就= achievementDao.findForGoal(realm,goalId)的抽象;'......但那只是我。 – EpicPandaForce

回答

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

我的天堂」 t測試了這個代碼,但我打算有一個帶有一個ArrayList of GoalWrapper對象的RecyclerView.Adapter。

我的一個擔心的是,我從來沒有移除mGoal聽衆。我甚至需要刪除它嗎?在ArrayList獲取GC的情況下會發生什麼?我認爲目標字段和附加到它的所有聽衆都得到了GC。

+0

如果僅當您在'onBindViewHolder()'中調用'realmResults.get(i)'時創建GoalWrapper,那麼您將保持懶惰評估,而不必將所有目標保留在ArrayList中。 – EpicPandaForce

+0

Doesn '這是因爲每次都必須重新運行findResultForGoal,而不是在第一次查詢目標時再次運行。 calculateStats實現未顯示,但它必須遍歷結果中的每個Achievement。 – grantka

+0

well * that's * true ...取決於元素的數量,太多'findAll()'調用可能會導致速度變慢。 ArrayList也可以,是的。 – EpicPandaForce