2017-02-24 54 views
2

,我需要解決把數據傳送到數據庫的境界像這樣:領域添加項目RealmList被添加到RealmObject

我有一個名爲obtained_code的對象; 我有一個名爲Offer的對象獲得代碼realmList; 我分別下載獲得的代碼,並通過他們的offer ID將它們分配給每個對象的列表。問題是,我不能添加它們,因爲當我檢查的大小,它始終爲0。

下面是代碼:

ObtainedCodes codes = response.body(); 
       for (ObtainedCode c : codes.getObtainedCodes()) { 
        Offer offer = RealmController.with(SplashActivity.this).getOffer(c.getOffer_id()); 
        if (offer != null) { 
         Log.d("Size", "Offer not null"); 
         realm1.beginTransaction(); 
         RealmList<ObtainedCode> list = offer.getObtained_codes(); 
         if (!list) { // if the 'list' is managed, all items in it is also managed 
          RealmList<ObtainedCode> managedImageList = new RealmList<>(); 
          for (ObtainedCode item : list) { 
           if (item) { 
            managedImageList.add(item); 
           } else { 
            managedImageList.add(realm1.copyToRealm(item)); 
           } 
          } 
          list = managedImageList; 
         } 

         offer.setObtained_codes(obtainedCodes); 
         Log.d("Size", String.valueOf(offer.getObtained_codes().size())); 
         realm1.copyToRealmOrUpdate(offer); 
         realm1.commitTransaction(); 
        } 
        offer = RealmController.with(SplashActivity.this).getOffer(c.getOffer_id()); 
        Log.d("Size", String.valueOf(offer.getObtained_codes().size())); 
       } 
+0

什麼之前'ObtainedCodes代碼行= response.body();'? – EpicPandaForce

+0

....哦,上帝。 'RealmController'?這是否基於Ravi Tamada的怪誕再次? – EpicPandaForce

+0

沒有。迴應來自改造呼叫。 – Traabefi

回答

2

1)上InfoHive拉維玉田教程是一塌糊塗請參閱my remake of that example instead

如果你設法開始使用0.82.1,因爲Ravi Tamada聲稱一個4歲的版本是「穩定的」,那麼我知道它不是。使用1.2.0(或最新版本爲3.4.1)

並且如果看到RealmController.with(),則運行,因爲它忽略線程限制。當你嘗試從後臺線程訪問它時,它會崩潰。

在後臺線程,你需要做的

@Override 
public void run() { 
    try(Realm realm = Realm.getDefaultInstance()) { 
     repository.whatever(realm); // pass Realm instance to database methods 
    } // auto-close 
    // end of thread 
} 

2)你是在UI線程上執行寫操作,這是不好的,從UI線程你應該使用realm.executeTransactionAsync(),但在你應該使用Ęxecutors.newSingleThreadedPool()在後臺線程上實際執行Retrofit調用,並用call.execute()而不是call.enqueue()來調用它。

3.)您應該在後臺線程上寫入Realm,並在UI線程上使用RealmChangeListener來偵聽寫入。

4.)您的代碼不起作用,因爲您將託管列表設置爲託管RealmObject。

您應該修改RealmObject中的現有RealmList,並僅向其添加託管對象。


Executor executor = Executors.newSingleThreadExecutor(); // field variable 
// ... 

void someMethod() { 
    executor.execute(new Runnable() { 
     @Override 
     public void run() { 
      Response<ObtainedCodes> response = retrofitService.getObtainedCodes().execute(); // run on current thread 
      ObtainedCodes codes = response.body(); 
      if(codes == null) return; 
      try(Realm r = Realm.getDefaultInstance()) { 
       r.executeTransaction(new Realm.Transaction() { 
        @Override 
        public void execute(Realm realm) { 
         for(ObtainedCode obtainedCode : codes.getObtainedCodes()) { 
          Offer offer = realmRepository.getOffer(realm, obtainedCode.getOfferId()); 
          if(offer == null) { 
           offer = realm.createObject(Offer.class, obtainedCode.getOfferId()); 
           // map properties to offer if possible 
          } 
          RealmList<ObtainedCode> offerCodes = offer.getObtainedCodes(); 
          ObtainedCode managedObtainedCode = realm.where(ObtainedCode.class).equalTo("obtainedCodeId", obtainedCode.getId()).findFirst(); 
          if(managedObtainedCode == null) { 
           managedObtainedCode = realm.createObject(ObtainedCode.class, obtainedCode.getId()); 
           // map properties from obtained code to managed obtained code 
          } 
          if(!offerCodes.contains(managedObtainedCode)) { 
           offerCodes.add(managedObtainedCode); 
          } 
         } 
        } 
       }); 
      } 
     } 
    }); 
} 
+0

Ooookay,謝謝。我會盡量明天實施你的建議。你能否也請寫一些例子來解決我的問題? – Traabefi

+0

我添加了一些示例代碼,我不能保證它可以開箱即用,因爲我不知道您的模式。 – EpicPandaForce

+0

其實我正在使用該呼叫和.enqueue(回叫)樣式。這意味着我必須重寫25%的代碼。好吧,讓我們來看看它是否會真正起作用 – Traabefi