2017-02-24 2 views
2

Ich muß die Daten in ein Reich Datenbank lösen wie folgt setzen:Realm Artikel in der Realmlist, das zu RealmObject hinzugefügt wird

Ich habe ein Objekt namens obtained_code; Ich habe eine RealmList von erhaltenen Codes in einem Objekt namens Angebot; Ich erhalte die erhaltenen Codes separat und ordne sie anhand ihrer Angebots-ID den Listen jedes Objekts zu. Das Problem ist, dass ich sie nicht hinzufügen können, denn wenn ich die Größe überprüfen, es ist immer 0.

Hier ist der Code:

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

Was ist die Linie, bevor 'ObtainedCodes Codes = response.body();'? – EpicPandaForce

+0

.... oh Gott. 'RealmController'? Basiert dies wieder auf Ravi Tamadas Monstrosität? – EpicPandaForce

+0

Es gibt keine. Die Antwort stammt vom Nachrüstungsaufruf. – Traabefi

Antwort

2

1.) die Ravi Tamada Tutorial auf InfoHive ist eine schreckliche Chaos , siehe my remake of that example instead.

Wenn Sie es geschafft haben, 0.82.1 zu verwenden, weil Ravi Tamada behauptete, dass eine 4 Jahre alte Version "stabil" ist, weiß ich, dass es nicht ist. Verwenden Sie stattdessen 1.2.0 (oder die neueste Version, die 3.4.1 ist)

Und wenn Sie eine RealmController.with() sehen, ausführen, weil es Thread-Beschränkung ignoriert. In dem Moment, in dem Sie versuchen, von einem Hintergrundthread darauf zuzugreifen, wird es abstürzen.

auf Hintergrund-Threads, müssten Sie

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

2.) Sie schreibt auf dem UI-Thread tun ausgeführt werden, das ist schlecht, von UI-Thread Sie realm.executeTransactionAsync(), aber in Ihre verwenden sollten In diesem Fall sollten Sie den Retrofit-Aufruf für einen Hintergrund-Thread unter Verwendung von Ęxecutors.newSingleThreadedPool() ausführen und ihn mit call.execute() anstelle von call.enqueue() aufrufen.

3.) Sie sollten in Realm auf dem Hintergrundthread schreiben, und auf dem UI-Thread sollten Sie RealmChangeListener verwenden, um auf Schreibvorgänge zu hören.

4.) Ihr Code funktioniert nicht, weil Sie eine nicht verwaltete Liste auf ein verwaltetes RealmObject setzen.

Sie sollten die vorhandene RealmList innerhalb des RealmObject ändern und nur verwaltete Objekte hinzufügen.


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, danke. Ich werde versuchen, Ihre Vorschläge morgen umzusetzen. Könnten Sie bitte auch ein Beispiel schreiben, das mein Problem löst? – Traabefi

+0

Ich habe einen Beispielcode hinzugefügt, ich kann nicht garantieren, dass es funktioniert, weil ich Ihr Schema nicht kenne. – EpicPandaForce

+0

Eigentlich verwende ich diesen Call und .enqueue (Callback) Stil. Das bedeutet, ich muss 25% meines Codes neu schreiben.Okay, lass uns ser, wenn es wirklich funktioniert – Traabefi

Verwandte Themen