有没有办法从AsyncTask调用Realm查询? 我有很多正在进行连接的查询,所以我想从单独的 One AsyncTask中调用它们以避免UI线程上的负载。现在我到处都在使用Realm的RealInstance。我收到此错误
Realm对象只能在创建它们的线程上访问
P.S 我知道Realm对每个查询都有自己的Async,但正如我刚才提到的,我有很多单独的调用,它们正在进行连接和循环。
修改
这是我的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;
}
答案 0 :(得分:6)
你只是have to do what the docs say:
对于AsyncTask,这是一个很好的模式:
try-with-resources
更重要的是,您可以使用protected Void doInBackground(Void... params) {
try(Realm realm = Realm.getDefaultInstance()) {
// ... Use the Realm instance ...
}
return null;
}
:
// 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();
如果您使用Thread或Runnable执行短期任务,建议使用以下模式:
RealmChangeListener
在UI线程上使用join
来通知后台线程中的成功事务。
编辑:哦,您想要执行异步查询。
我有很多正在进行连接的查询,所以我想从单独的One AsyncTask中调用它们以避免UI线程上的负载。
...虽然我真的怀疑你有任何“加入”,因为Realm不是一个关系数据库,并且AsyncTask
s的概念在Realm中不存在;如果你想要异步查询,你不应该使用像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);
这样的废话过度复杂化你的设计。只需使用the asynchronous query methods。
[]
答案 1 :(得分:2)
Realm具有Async加载默认功能: -
realm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
// Use the Realm instance
}
});
在后台线程上执行上面的操作,当db改变时,它会给出回调。
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
}
});
答案 2 :(得分:1)
我相信您在doInBackground
中创建了Realm对象,然后在onPostExecute
处理结果?为避免这种情况,您可以使用IntentService
代替AsyncTask
。如果您仍想使用AsyncTask
,也可以在doInBackground
中处理查询结果,然后将所需数据(列表,POJO等)返回到onPostExecute
。