Завершаемые функции удаления из реализации DAO создают исключение IllegalStateException - PullRequest
2 голосов
/ 18 марта 2019

Предположим, что у нас есть простой интерфейс DAO:

@Dao
interface MyDao {
    @Delete
    fun delete(entity: MyEntity): Completable
}

, и мы ожидаем от Room, что он сгенерирует функцию, которая возвращает Completable.Выполнение этого Completable должно удалить сущность из базы данных.

Теперь мы вызываем функцию delete в основном потоке, но подписываемся на нее в фоновом потоке.

// Called in the main thread
myDao.delete(myEntity)
    .subscribeOn(Schedulers.background())
    .subscribe()

Проблема состоит в том, что этот вызов приводит к IllegalStateException с таким сообщением:

Cannot access database on the main thread since it may potentially lock the UI for a long period of time.

Интересно, что другие функции, такие как, например, select (возвращает Single<MyEntity>), работают отлично, их можно создавать в главном потоке, ноони выполняются в фоновом потоке.Поэтому я посмотрел в сгенерированный класс, чтобы увидеть, какие функции предоставляют IllegalStateException в реализации удаления:

public SupportSQLiteStatement acquire() {
    assertNotMainThread();
    return getStmt(mLock.compareAndSet(false, true));
}

Вопрос в том, является ли это ошибкой или я должен вызывать удаление по-другому, например: Completale.defer { myDao.delete(myEntity)) }?

Редактировать

Если быть более точным: я использую пользовательский запрос для удаления ("DELETE FROM myentities WHERE id = :id) и вот сгенерированный код:

@Override
public Completable deleteByIdInternal(final long id) {
  final SupportSQLiteStatement _stmt = __preparedStmtOfDeleteByIdInternal.acquire();
  int _argIndex = 1;
  _stmt.bindLong(_argIndex, id);
  return Completable.fromCallable(new Callable<Void>() {
    @Override
    public Void call() throws Exception {
      __db.beginTransaction();
      try {
        _stmt.executeUpdateDelete();
        __db.setTransactionSuccessful();
        return null;
      } finally {
        __db.endTransaction();
        __preparedStmtOfDeleteByIdInternal.release(_stmt);
      }
    }
  });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...