web-dev-qa-db-ja.com

部屋で削除を実行する(rxjava)

部屋では、_@Delete_アノテーションは何も出力しません。これはdaoがどのように見えるかです

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

}
_

これは、次のようなことをしているときに問題になります

userRepository.deleteUser().subscribeOndaoからの放出がないため。次のコードを使用して、バックグラウンドスレッドでdeleteUserを呼び出します。

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

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


            }, this::handleError);
_

これは正常に機能します。ただし、subscribeメソッドでは、Android UIにアクセスして、削除が成功したことを通知するトーストを表示する必要があります。当然、この例外が発生します(observeOnがチェーンにないため)

_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.
_

この質問の情報に基づく: Run Void Method in Background(StackOverflow)

Completableを使用して、次のような別のスレッドでサブスクライブします。

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

私のために働いた。 clearCachedDataメソッドは、呼び出しているRoomでクエリを実行します。

私の質問は:

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

私はこれが遅いことを知っています。しかし、私は同じ問題に遭遇し、以下でそれを解決することができました

Daoクラスで

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

このように呼んでください。このようにしてサブスクライブでき、バックグラウンドで実行されます。

Single.fromCallable {
        user.deleteAllUser() //User Dao fun
    }
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(..do stuff..)
2
Abhi

ユーザーのリストを削除機能に渡して、削除されたユーザーの数を返すようにしてください(コードは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
    }
}
0
moonlady16

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() {
                    }
                });
0
kinjal patel