2016-11-09 2 views
1

Есть ли способ вызвать запросы Realm от AsyncTask? У меня так много запросов, которые делают join, поэтому я хочу назвать их из отдельного One AsyncTask, чтобы избежать загрузки в потоке пользовательского интерфейса. Пока я использую DefaultInstance of Realm всюду. Я получаю эту ошибкуВызов области из AsyncTask

Realm объекты могут быть доступны только на нить они где созданный

PS Я знаю Realm имеет свой собственный Async для каждого запроса, но, как я только что сказал я есть много отдельных вызовов, которые далее выполняют объединения и для циклов.

EDIT

вот мой код для асинхронного

@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

Некоторые примеры кода ... https://github.com/realm/realm-java/blob/master/examples/threadExample/src/main/java/io/realm/examples/threads/AsyncTaskFragment. java –

+0

спасибо ..! Итак, это ключ, мне нужно получить DefaultInstance внутри doinBackground? – Ajji

+1

Не могу ответить на это. Никогда не использовал Realm. Просто очень полезно использовать Google для людей. –

ответ

4

Вы просто have to do what the docs say:

Для AsyncTask это хорошая картина:

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

    return null; 
} 

Если вы используете тему или Runnable для короткоживущих задач, модель следует за рекомендуется:

// 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(); 

И используйте RealmChangeListener в потоке пользовательского интерфейса, чтобы получать уведомления об успешных транзакциях в фоновом режиме.



EDIT: Ах, вы хотите, чтобы выполнять асинхронные запросы.

У меня так много запросов, которые делают соединение, поэтому я хочу назвать их из отдельной One AsyncTask, чтобы избежать загрузки в потоке пользовательского интерфейса.

... в то время как я действительно сомневаюсь, что есть какие-либо «присоединиться к» s рассматривает Realm не является реляционной базой данных и концепция join с не существует в царстве; если вы хотите асинхронных запросов, вы не должны чрезмерно усложнять свой дизайн с ерундой, как AsyncTask. Просто используйте 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

Извините, я получаю исключение, когда пытаюсь реализовать это решение через несколько дней. В нем говорится: «Доступ к Realm из неправильного потока. Объекты Realm могут быть доступны только в потоке, который был создан» В классе Application это первый раз инициализируется realm: realmConfig = new RealmConfiguration.Builder (this) .build (this) .build (this) .build (this) .build (this) .build (this) .build (this) .build (this) .build); Realm.setDefaultConfiguration (realmConfig); А затем в Async, я получаю экземпляр по умолчанию: Любая помощь? – Ajji

+0

Я не могу ответить на этот вопрос без фактического кода, который выдает это исключение. – EpicPandaForce

+0

Я отредактировал вопрос, пожалуйста, проверьте. – Ajji

1

Я считаю, что вы создаете объекты Realm в doInBackground, а затем результаты процесса в onPostExecute? Чтобы этого избежать, вы можете использовать IntentService вместо AsyncTask. Если вы все еще хотите использовать AsyncTask, вы также можете обрабатывать результаты запроса в doInBackground, а затем возвращать необходимые данные (списки, POJO и т. Д.) До onPostExecute.

+0

Ahh, Да, я думаю, это то, чего мне не хватало. Позвольте мне попробовать образец, и я могу отметить этот ответ, как принято. – Ajji

2

Realm имеет Async функциональность нагрузки по умолчанию: -

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

Над исполнением сделано на фоне потока, и это дает обратный вызов, когда дБ изменения типа.

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 
      } 
     });