bar*_*rbs 5 android kotlin rx-java2 android-room
我正在研究Rxjava2,并且正在尝试将Room Library与Rxjava2集成。问题是:我有一个填充的表,每次登录该应用程序时,都需要删除该表,然后在数据库中插入新内容。另外,在删除和插入工作正常,但是当我尝试我删除该表的内容后插入新值,删除方法删除所有的新的价值观。(代码的某些部分是在科特林和其他JAVA)
我已经尝试了以下方法:RxJava2 + Room:在clearAllTables()调用之后没有将数据插入DB中,但是没有成功。
道
@Dao
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(list:List<Something>)
@Query("DELETE FROM SomethingTable")
fun delete()
@Query("SELECT * FROM SomethingTable")
fun getAll(): Flowable<List<Something>>
Run Code Online (Sandbox Code Playgroud)
我的班级叫DAO(CallDao)
//insert
fun insertInDB(list: List<Something>) {
Completable.fromAction {
dbDAO!!.insert(list)
}.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe()
}
//delete
fun clean() {
Completable.fromAction {
dbDAO!!.delete()
}.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.single())
.subscribe()
}
//search all
fun findAll(): Observable<List<Something>>? {
return Observable.create { subscriber ->
dbDAO!!.getAll()
.subscribeOn(Schedulers.io())
.subscribe {it->
subscriber.onNext(it)
}
}
}
Run Code Online (Sandbox Code Playgroud)
单击登录按钮时调用的方法
private void clearAndInsertInDB() {
CallDao callDao= new CallDao(getActivity());
//delete all table values
callDao.clean();
Something sm = new Something("test1", "test2");
ArrayList<Something> list = new ArrayList<>();
list.add(sm);
list.add(sm);
//insert new values
callDao.insertInDB(list);
//get all new values in DB
callDao.findAll()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(res -> {
//here gives me a IndexOutOfBoundsException
Log.d("logDebug", res.get(0).getCodeExemple());
});
}
Run Code Online (Sandbox Code Playgroud)
我的代码中也可以进行任何更正:),但是主要问题是delete方法删除所有新的插入值,并且应该只删除旧的值。
dgl*_*ano 11
您正在进行两个异步调用:一个删除用户,另一个调用再次插入。但是,即使先调用该callDao.clean();方法,然后再调用callDao.insertInDB(list);,也不能保证clean()操作将在insertInDB()操作之前完成(因为这就是异步调用的工作方式)。
这是正在发生的事情:
相反,您应该将异步调用链接起来,这样就可以在知道第一个已完成后立即调用第二个。
如何使用RxJava和实现Completable呢?按照此答案andThen所述使用运算符
您应该修改clean()和insertInDB()方法以返回Completables,andThen用来链接它们,然后进行订阅。
使用RxJava和andThen()的简单示例
FakeDatabase db = Room.databaseBuilder(this, FakeDatabase.class, "fake.db")
.fallbackToDestructiveMigration()
.build();
UserDao userDao = db.userDao();
User user1 = new User("Diego", "Garcia Lozano", "diegogarcialozano@fake.com");
User user2 = new User("Juan", "Perez", "juanperez@fake.com");
User user3 = new User("Pedro", "Lopez", "pedrolopez@fake.com");
List<User> users = new ArrayList<>();
users.add(user1);
users.add(user2);
users.add(user3);
Completable deleteAllCompletable = Completable.fromAction(userDao::deleteAll);
Completable insertUserCompletable = Completable.fromAction(() -> userDao.insertAll(users));
deleteAllCompletable
.andThen(Completable.fromAction(() -> System.out.println("Delete finished")))
.andThen(insertUserCompletable)
.andThen(Completable.fromAction(() -> System.out.println("Insert finished")))
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.single())
.subscribe();
Run Code Online (Sandbox Code Playgroud)
检查Logcat执行后,您可以看到操作以正确的顺序执行:
2018-11-19 16:07:02.056 10029-10047/? I/System.out: Delete finished
2018-11-19 16:07:02.060 10029-10047/? I/System.out: Insert finished
Run Code Online (Sandbox Code Playgroud)
之后,我使用SQLite浏览器工具检查了数据库的内容,发现插入工作正常。
在DAO中使用@Transaction
您RxJava根本不需要使用就可以获得更好的解决方案。相反,您可以Transaction使用@Transaction批注在DAO中定义一个,如本博文所述。它看起来像这样:
道
@Dao
public abstract class UserDao {
@Transaction
public void deleteAndCreate(List<User> users) {
deleteAll();
insertAll(users);
}
@Query("DELETE FROM User")
public abstract void deleteAll();
@Insert
public abstract void insertAll(List<User> users);
}
Run Code Online (Sandbox Code Playgroud)
活动
Completable.fromAction(() -> userDao.deleteAndCreate(users))
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.single())
.subscribe();
Run Code Online (Sandbox Code Playgroud)
检查桌子
就个人而言,我会使用@Transaction注释。
| 归档时间: |
|
| 查看次数: |
2216 次 |
| 最近记录: |