从AsyncTask调用领域

时间:2016-11-09 06:08:28

标签: android android-asynctask realm

有没有办法从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;
    }

3 个答案:

答案 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