Issue
Is there any way to call Realm queries from AsyncTask? I have so many queries that are doing join, So i want to call them from a separate One AsyncTask to avoid the load on UI Thread. For now i am using DefaultInstance of Realm everywhere. I get this error
Realm objects can only be accessed on the thread they where created
P.S I know Realm has its own Async for every query, but as i just mentioned i have alot of separate calls that are further doing joins and for loops.
EDIT
here's my code for an 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;
}
Solution
You just have to do what the docs say:
For AsyncTask this is a good pattern:
protected Void doInBackground(Void... params) {
Realm realm = null;
try {
realm = Realm.getDefaultInstance();
// ... Use the Realm instance ...
} finally {
if (realm != null) {
realm.close();
}
}
return null;
}
More importantly, you can use try-with-resources
:
protected Void doInBackground(Void... params) {
try(Realm realm = Realm.getDefaultInstance()) {
// ... Use the Realm instance ...
}
return null;
}
If you are using Thread or Runnable for short-lived tasks, the follow pattern is recommended:
// 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();
And use a RealmChangeListener
on the UI thread to be notified of successful transactions in background threads.
EDIT: Oh, you want to perform asynchronous queries.
I have so many queries that are doing join, So i want to call them from a separate One AsyncTask to avoid the load on UI Thread.
...while I truly doubt you have any "join"s considering Realm is not a relational database and the concept of join
s doesn't exist in Realm; if you want asynchronous queries, you shouldn't overcomplicate your design with nonsense like AsyncTask
. Just use 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);
Answered By - EpicPandaForce
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.