2016-11-05 3 views
2

Я думал, что после рекомендуемого Realm подход для выполнения вставки данных ASync так:Ваш Realm открывается из потока без Looper

public void addCustomer(final Customer customer) { 
     Realm insertRealm = Realm.getDefaultInstance(); 
     insertRealm.executeTransactionAsync(new Realm.Transaction() { 
      @Override 
      public void execute(Realm backgroundRealm) { 
       long id = customerPrimaryKey.incrementAndGet(); 
       customer.setId(id); 
       backgroundRealm.copyToRealm(customer); 
      } 
     }, new Realm.Transaction.OnSuccess() { 
      @Override 
      public void onSuccess() { 
       Log.d(LOG_TAG, "Customer Added"); 
      } 
     }, new Realm.Transaction.OnError() { 
      @Override 
      public void onError(Throwable error) { 
       Log.d(LOG_TAG, error.getMessage()); 
      } 
     }); 

     insertRealm.close(); 

    } 

Однако, когда я запускаю приведенный выше код я получаю «Your Realm открывается из потока без Looper, и вы предоставили обратный вызов, нам нужен обработчик для вызова вашего обратного вызова »

Я запускаю этот код в классе без активности, что я делаю неправильно здесь и как я могу исправить Это. Благодарю.

Update - Фиксированные Оказывается, что нет ничего плохого в запросе, проблема заключается в том, что я звала его из IntentService. Я пытался засеять базу данных на приложение первого запуска, так что я установил это так:

protected void onHandleIntent(Intent intent) { 
     Realm realm = Realm.getDefaultInstance(); 

     //Add sample Customers to database 
     List<Customer> customers = SampleCustomerData.getCustomers(); 

     realm.beginTransaction(); 
     for (Customer customer: customers){ 
      customer.setId(customerPrimaryKey.getAndIncrement()); 
      realm.copyToRealm(customer); 
     } 
     realm.commitTransaction(); 

realm.close(); 

    } 

То фиксирована, вне IntentService, запрос отлично работает при вызове из UI Thread.

+1

Это вызвано из класса Presenter. Я не начинал нить, я верю, что в Realm вращается собственный поток для выполнения асинхронного запроса. –

ответ

0

Вам необходимо позвонить по номеру addCustomer из нити пользовательского интерфейса.

+0

Хм, на самом деле это вызвано из onHandleIntent IntentService, поэтому позвольте мне посмотреть, если это проблема. –

1

Realm полагается на связь потоков Android с помощью классов Hanfler и Looper. Похоже, вы запрашиваете операцию async с другого фона Thread (почему ?, это уже в фоновом режиме, используйте синхронную версию). Чтобы исправить это, вам понадобится нить с Active Looper. Используйте поток Handler в качестве фоновой нити - он будет инициализирован Looper

+0

Не могли бы вы предоставить пример, я запускаю код из репозитория, который вызывается ведущим. У меня есть доступ к объекту Context в этом классе, как я могу исправить проблему. –

+0

http://stackoverflow.com/questions/25094330/example-communicating-with-handlerthread –

0

Попробуйте эту строку

insertRealm.close(); 

добавить в onSuccess и onError метода. Удалите его из последней строки, как сейчас.

Так что ваш код будет выглядеть

public void addCustomer(final Customer customer) { 
     final Realm insertRealm = Realm.getDefaultInstance(); 
     insertRealm.executeTransactionAsync(new Realm.Transaction() { 
      @Override 
      public void execute(Realm backgroundRealm) { 
       long id = customerPrimaryKey.incrementAndGet(); 
       customer.setId(id); 
       backgroundRealm.copyToRealm(customer); 
      } 
     }, new Realm.Transaction.OnSuccess() { 
      @Override 
      public void onSuccess() { 
       Log.d(LOG_TAG, "Customer Added"); 
       insertRealm.close(); 
      } 
     }, new Realm.Transaction.OnError() { 
      @Override 
      public void onError(Throwable error) { 
       Log.d(LOG_TAG, error.getMessage()); 
       insertRealm.close(); 
      } 
     }); 
    } 
1

Для того, чтобы

insertRealm.executeTransactionAsync(new Realm.Transaction() { 
     @Override 
     public void execute(Realm backgroundRealm) { 
      //... 
     } 
    }, new Realm.Transaction.OnSuccess() { 
     @Override 
     public void onSuccess() { 
      // !!! 
     } 
    }, new Realm.Transaction.OnError() { 
     @Override 
     public void onError(Throwable error) { 
      // !!! 
     } 
    }); 

асинхронными транзакций будет называться на фоне потока, поток должен быть связан с Looper (и, следовательно, есть Handlers, которые могут связываться с нитью с помощью Looper).


Решение, используйте синхронную транзакцию в фоновом режиме.

Но вы уже это поняли.

protected void onHandleIntent(Intent intent) { 
    Realm realm = null; 
    try { 
     realm = Realm.getDefaultInstance(); 
     final List<Customer> customers = SampleCustomerData.getCustomers(); 
     realm.executeTransaction(new Realm.Transaction() { 
      @Override 
      public void execute(Realm realm) { 
       for (Customer customer: customers){ 
        customer.setId(customerPrimaryKey.getAndIncrement()); 
        realm.insert(customer); 
       } 
      } 
     }); 
    } finally { 
     if(realm != null) { 
      realm.close(); 
     } 
    } 
} 
Смежные вопросы