Nano Hash - криптовалюты, майнинг, программирование

Выполнение удаления с комнатой (rxjava)

В комнате аннотация @Delete ничего не излучает. Вот так выглядит dao

@Dao
public interface UserDao {
    @Delete
    void deleteUser(User user);
    //We can't use Maybe or Single or anything here

}

Это создает проблему при выполнении чего-то вроде

userRepository.deleteUser().subscribeOn, так как у нас нет эмиссии на dao. Я использую следующий код для вызова deleteUser в фоновом потоке.

Observable.just(appDatabase).
            subscribeOn(SchedulerProvider.getInstance().computation()).

            subscribe(db -> {
                userRepository.logoutUser(loggedUser.getLoggedInUser());
                loggedUser.setLoggedInUser(null);


            }, this::handleError);

Это прекрасно работает. Однако в методе подписки мне теперь нужно получить доступ к пользовательскому интерфейсу Android, чтобы отобразить всплывающее уведомление об успешном удалении. Естественно, я получаю это исключение (поскольку в цепочке отсутствуетObservOn)

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

Однако, когда я поставил observeOn вот так

Observable.just(appDatabase).
        subscribeOn(SchedulerProvider.getInstance().computation()).
        observeOn(SchedulerProvider.getInstance().ui()).
        subscribe(db -> {
            userRepository.logoutUser(loggedUser.getLoggedInUser());
            loggedUser.setLoggedInUser(null);

            Message message = new Message(R.string.user_logged_out_msg);
            message.setMessageType(Message.MessageType.SUCCESS_MESSAGE);
            view.showMessages(Arrays.asList(message)); //this leads to a taost

        }, this::handleError);

Я странно получаю это исключение:

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

  • Хотя у меня нет для вас окончательного ответа, я могу сказать, что Room по умолчанию выполняет вызовы RXJava в фоновом потоке, поэтому вам не нужно явно вызывать subscibeOn(), но вам нужно убедиться, что вы делаете вызов для наблюдения за отправкой активности в поток пользовательского интерфейса. Это та область, на которую я бы обратил внимание на вашем месте. 21.12.2017
  • Я использую следующий код для вызова deleteUser в фоновом потоке — вы не вызываете deleteUser(). Вы можете синхронизировать свои примеры, чтобы они были согласованы. 21.12.2017

Ответы:


1

На основе информации из этого вопроса: Запустить метод Void в фоновом режиме (StackOverflow)

Использование Completable и подписка на другой поток, например:

Completable.fromAction(this::clearCachedData)
   .subscribeOn(Schedulers.io())
   .subscribe();

работал на меня. clearCachedData выполняет запрос в комнате, которую я вызываю.

Мой запрос:

/**
 * Delete all data in the items table.
 */
@Query("DELETE FROM items")
void deleteWeatherItems();
19.09.2018

2

Я знаю, что это поздно. Но я столкнулся с той же проблемой и смог решить ее, выполнив следующие действия.

В классе Дао

@Query("DELETE FROM users")
    fun deleteAllUser()

Назовите это так. Таким образом, вы можете подписаться, и он будет работать в фоновом режиме.

Single.fromCallable {
        user.deleteAllUser() //User Dao fun
    }
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(..do stuff..)
23.05.2018
  • Single.fromCallable ожидает, что будет возвращено значение. И вы не можете вернуть null, потому что он вылетает с io.reactivex.exceptions.OnErrorNotImplementedException: The callable returned a null value 12.07.2018
  • @HughHughTeotl возвращает единицу, а не ноль. 29.01.2019

  • 3

    Замените метод Observable just на create.

      Observable.create(new ObservableOnSubscribe<Object>() {
                @Override
                public void subscribe(@io.reactivex.annotations.NonNull ObservableEmitter<Object> e) throws Exception {
                    e.onNext(tileDatabase.getCategoryDeo().deleteCategory(category));
    
                }
            })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<Object>() {
                        @Override
                        public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) {
                        }
    
                        @Override
                        public void onNext(@io.reactivex.annotations.NonNull Object o) {
                            Toast.makeText(MainActivity.this, "Record deleted ", Toast.LENGTH_SHORT).show();
                        }
    
                        @Override
                        public void onError(@io.reactivex.annotations.NonNull Throwable e) {
                        }
    
                        @Override
                        public void onComplete() {
                        }
                    });
    
    21.12.2017
  • Это выглядит правдоподобно. Я сделаю это через несколько минут. 21.12.2017

  • 4

    Попробуйте передать список пользователей в функцию удаления и вернуть количество удаленных пользователей (код на Kotlin).

    @Dao
    public interface UserDao {
        ...
    
        @Delete
        fun deleteUsers(users: List<User>): Int
    }
    

    Это будет класс базы данных:

    @Database(entities = [User::class], version = 1)
    abstract class UsersDatabase : RoomDatabase() {
    
        abstract fun userDao(): UserDao
    
        companion object {
            private var INSTANCE: UsersDatabase? = null
    
            fun getInstance(context: Context): UsersDatabase? {
                if (INSTANCE == null) {
                    INSTANCE = Room.databaseBuilder(context.applicationContext, UsersDatabase::class.java, "my_database.db").build()
                }
                return INSTANCE
            }
    
            ...
    }
    

    И это репозиторий и viewModel (Room Android Architecture):

    class UsersRepository internal constructor(val application: Application) {
    
       private val userDao: UserDao = UsersDatabase.getInstance(application)!!.userDao()
    
       ...
    
       fun deleteUsers(users: List<User>): Single<Int> {
            return Single.fromCallable { userDao.deleteUsers(users) }
        }
    }
    
    
    class UsersViewModel(val app: Application) : AndroidViewModel(app) {
        private val repo: UsersRepository = UsesRepository(application = app)
        ...
    
        fun deleteUsers(users: List<User>): Single<Int> {
            return repo.deleteUsers(users).subscribeOn(Schedulers.io())
        }
    }
    

    А затем в каком-то действии или фрагменте:

    class UsersActivity : AppCompatActivity() {
    
        private lateinit var viewModel: UsersViewModel
        ...
    
        override fun onCreate(savedInstanceState: Bundle?) {
        ...
           viewModel = ViewModelProviders.of(this).get(UsersViewModel::class.java)
        }
    
        fun removeUsers(users: List<User>) {
           ...
           viewModel.deleteUsers(users).subscribe(this::toast)
        }
        ...
    
        fun toast() {
            Toast.make(this, "Users deleted", Toast.LENGTH_SHORT).show
        }
    }
    
    11.09.2018

    5
    @Query("DELETE FROM User.TABLE_NAME")
    public void nukeTable();
    
    @Query("DELETE FROM " + User.TABLE_NAME + " WHERE " + User.COLUMN_ID + " = :id")
    int deleteById(long id);
    

    Эти методы могут быть полезны.

    21.12.2017
  • как справиться с этим с помощью rx java 10.04.2018
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..