2016-11-09 11 views
1

Gibt es eine Möglichkeit, Realm-Abfragen von AsyncTask aus aufzurufen? Ich habe so viele Anfragen, die tun Join, also möchte ich sie von einem separaten One AsyncTask aufrufen, um die Belastung auf UI Thread zu vermeiden. Momentan benutze ich DefaultInstance of Realm überall. Ich erhalte diese StörungRealm von AsyncTask aufrufen

Realm-Objekte können nur auf dem Thread zugegriffen werden sie geschaffen, in dem

PS Ich weiß Realm seine eigene Async für jede Abfrage, aber wie ich, dass ich nur eine Menge erwähnt haben von separaten Aufrufen, die weiterhin Joins und for-Schleifen durchführen.

EDIT

hier ist mein Code für eine Async

@Override 
    protected Object doInBackground(Object[] params) { 
     //Step 1: Find All quote_taxes 
     Realm realm = Realm.getDefaultInstance(); 
     listTaxData = new ArrayList<TaxData>(); 
     try { 
      RealmResults<quote_taxes> listQuoteTaxes = quote_taxes.get_from_quotes(realm, quote.getId()); 
      if (listQuoteTaxes != null && listQuoteTaxes.size() > 0) { 
       for (quote_taxes quoteTax : listQuoteTaxes) { 
        TaxData taxData = new TaxData(); 
        taxData.setTaxName(quoteTax.getTaxName()); 
        taxData.setAccountNumber("" + quoteTax.getAccountNumber()); 
        taxData.setTaxRate("" + quoteTax.getTaxRate() + "%"); 
        double total = quote_taxes.total(realm, quoteTax); 
        showLog("Total = " + total); 
       } 
      } 
     }catch (Exception ex) 
     { 

     }finally { 
      realm.close(); 
     } 
     return null; 
    } 
+1

Einige Codebeispiel ... https://github.com/realm/realm-java/blob/master/examples/threadExample/src/main/java/io/realm/examples/threads/AsyncTaskFragment. Java –

+0

Danke ..! Also das ist der Schlüssel, ich muss DefaultInstance in doinBackground abrufen? – Ajji

+1

Kann das nicht beantworten. Nie benutzt Realm. Nur wirklich gut in der Verwendung von Google für Menschen –

Antwort

4

Sie haben soeben have to do what the docs say:

Für AsyncTask dies ein gutes Muster ist:

protected Void doInBackground(Void... params) { 
    Realm realm = null; 
    try { 
     realm = Realm.getDefaultInstance(); 
     // ... Use the Realm instance ... 
    } finally { 
     if (realm != null) { 
      realm.close(); 
     } 
    } 

    return null; 
} 

Wenn Sie Gewinde oder Runnable für kurzlebige Aufgaben verwenden, die Nachfolgemuster empfohlen:

// Run a non-Looper thread with a Realm instance. 
Thread thread = new Thread(new Runnable() { 
    @Override 
    public void run() { 
     Realm realm = null; 
     try { 
      realm = Realm.getDefaultInstance(); 
      // ... Use the Realm instance ... 
     } finally { 
      if (realm != null) { 
       realm.close(); 
      } 
     } 
    } 
}); 

thread.start(); 

Und verwenden Sie eine RealmChangeListener auf dem UI-Thread, um über erfolgreiche Transaktionen in Hintergrundthreads benachrichtigt werden.



EDIT: Oh, wollen Sie asynchrone Abfragen durchzuführen.

Ich habe so viele Abfragen, die tun Join, also möchte ich sie von einer separaten One AsyncTask aufrufen, um die Last auf UI Thread zu vermeiden.

... während ich wirklich Zweifel haben Sie eine „join“ s unter Berücksichtigung Realm nicht eine relationale Datenbank ist und das Konzept der join s nicht in Realm existieren; Wenn Sie asynchrone Abfragen wollen, sollten Sie Ihr Design mit Unsinn wie AsyncTask nicht überkomplizieren. Verwenden Sie einfach the asynchronous query methods.

RealmResults<Something> results; 
RealmChangeListener realmChangeListener = new RealmChangeListener() { 
    @Override 
    public void onChange(Object element) { 
     if(results != null && results.isValid() && results.isLoaded()) { 
      updateUI(results); 
     } 
    } 
}; 

//... 

results = realm.where(Something.class)./*...*/.findAllAsync(); // <-- async query 
results.addChangeListener(realmChangeListener); 
+0

Es tut mir leid, ich bekomme eine Ausnahme, als ich versuchte, diese Lösung nach wenigen Tagen zu implementieren. Es heißt "Realm-Zugriff von falschem Thread. Auf Realm-Objekte kann nur auf den Thread zugegriffen werden, in dem sie erstellt wurden" In der Application-Klasse wird Realm erstmalig initialisiert: realmConfig = new RealmConfiguration.Builder (this) .build (); Realm.setDefaultConfiguration (realmConfig); Und dann in Async, bekomme ich die Standardinstanz: Irgendwelche Hilfe? – Ajji

+0

Ich kann das ohne den tatsächlichen Code, der diese Ausnahme auslöst, nicht beantworten. – EpicPandaForce

+0

Ich habe die Frage bearbeitet, bitte überprüfen. – Ajji

1

Ich glaube, dass Sie Realm Objekte in doInBackground und dann Prozessergebnisse in onPostExecute erstellen? Um dies zu vermeiden, können Sie IntentService anstelle von AsyncTask verwenden. Wenn Sie weiterhin AsyncTask verwenden möchten, können Sie die Abfrageergebnisse auch in doInBackground bearbeiten und dann die benötigten Daten (Listen, POJOs usw.) an onPostExecute zurückgeben.

+0

Ahh, ich denke, das ist es, was ich vermisste. Lassen Sie mich eine Probe versuchen und ich kann diese Antwort als akzeptiert markieren. – Ajji

2

Realm hat seine Async Last Standardfunktionalität: -

realm.executeTransactionAsync(new Realm.Transaction() { 
       @Override 
       public void execute(Realm realm) { 
        // Use the Realm instance 
        } 
      }); 

Vor Ausführung auf Hintergrund-Thread getan, und es ist gibt Rückruf bei db Änderungen wie.

realm.executeTransaction(new Realm.Transaction() { 
      @Override 
      public void execute(Realm realm) { 

      } 
     }, new Realm.Transaction.OnSuccess() { 
      @Override 
      public void onSuccess() { 
       // success callback 
      } 
     }, new Realm.Transaction.OnError() { 
      @Override 
      public void onError(Throwable error) { 
       // error callback 
      } 
     });