java - 如何使用 Rxjava 预填充 android 房间数据库
问题描述
如何使用 Rxjava 正确预填充我的数据库
这是我的道
@Query("SELECT * from questions WHERE difficulty = :difficulty")
Flowable<List<Question>> getQuestions(String difficulty);
// Emits the number of users added to the database.
@Insert
public Maybe<long[]> insertQuestions(List<Question> questions);
这是我的数据库类
public static synchronized QuestionDatabase getInstance(Context context) {
if (instance == null) {
instance = Room.databaseBuilder(context.getApplicationContext(), QuestionDatabase.class, "questions_database")
.fallbackToDestructiveMigration()
//.addMigrations(MIGRATION_1_2)
.addCallback(roomCallback)
.build();
}
return instance;
}
private static RoomDatabase.Callback roomCallback = new RoomDatabase.Callback() {
@Override
public void onCreate(@NonNull SupportSQLiteDatabase db) {
super.onCreate(db);
QuestionDao questionDao = instance.questionDao();
List<Question> questions = new ArrayList<>();
questions.add(new Question("A is correct", "A", "B", "C", 1, GameConstants.DIFFICULTY_EASY));
questions.add(new Question("C is correct", "A", "B", "C", 3, GameConstants.DIFFICULTY_HARD));
questions.add(new Question("B is correct", "A", "B", "C", 2, GameConstants.DIFFICULTY_EASY));
//inserting records
questionDao.insertQuestions(questions)
.subscribeOn(Schedulers.io())
//.observeOn(AndroidSchedulers.mainThread())
.subscribe(
new Consumer<long[]>() {
@Override
public void accept(long[] longs) throws Exception {
}
},
new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
}
});
}
};
我遇到的问题如下:
仅当我在活动 p.Ex 上调用方法时才会填充数据库:
//getting flowable to subscribe consumer that will access the data from Room database.
questionDao.getQuestions(GameConstants.DIFFICULTY_HARD)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
new Consumer<List<Question>>() {
@Override
public void accept(List<Question> questions) throws Exception {
questionList = (ArrayList<Question>)questions;
questionCountTotal = questionList.size();
Collections.shuffle(questionList);
showNextQuestion();
}
},
new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
}
}
);
当我调用这个方法时,我得到了两次问题。我通过在 questionDao.getQuestions 的接受方法中放置一个断点来检查这一点。我相信有两个线程正在运行,一个用于填充,另一个用于获取问题。
为什么会发生这种情况,我该如何以正确的方式实现它?
提前致谢
解决方案
我相信以下更改将起作用
- 更改getInstance方法以强制打开数据库,从而导致onCreate在您获取实例时运行,而不是在您尝试访问数据库之前运行。
根据(见评论): -
public static synchronized QuestionDatabase getInstance(Context context) {
if (instance == null) {
instance = Room.databaseBuilder(context.getApplicationContext(), QuestionDatabase.class, "questions_database")
.fallbackToDestructiveMigration()
//.addMigrations(MIGRATION_1_2)
.addCallback(roomCallback)
.build();
}
instance.getOpenHelper().getWritableDatabase(); //<<<<<<<<<< Forces an Open thus creation of the Database
return instance;
}
- 添加初始问题而不订阅
即代替
//inserting records
questionDao.insertQuestions(questions)
.subscribeOn(Schedulers.io())
//.observeOn(AndroidSchedulers.mainThread())
.subscribe(
new Consumer<long[]>() {
@Override
public void accept(long[] longs) throws Exception {
}
},
new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
}
});
只需使用:-
questionDao.insertQuestions(questions);
当您在活动中恢复实例时,将填充数据库。
推荐阅读
- r - Error warning while using the getSymbols function in R
- excel - 从 VBA 发出 2 封不同的电子邮件
- ios - Vimeo Iframe 在 Ipad 中 15 秒后停止
- node.js - 无法通过 nodejs express 后端加载 create-react-app
- android - 如何在颤动上读取BLE和应用程序之间的字符串
- reactjs - 通过 NextJS 中的 useEffect 监听路由器变化
- objective-c - 如何拦截发送到可编辑 NSTextField 的所有关键事件
- xcode - Xcode 模拟器中的配额超出错误是什么?
- gitlab-api - 使用 Gitlab API 搜索文件
- ruby-on-rails - 如果 Rails 模型中存在关联,如何给属性取别名?