Как предварительно заполнить базу данных android комнат Rxjava - PullRequest
0 голосов
/ 06 января 2020

Как правильно предварительно заполнить базу данных, используя Rx java

Вот мой дао

@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 {

                }
            }
    );

И когда я вызываю этот метод, я получаю вопросы дважды. Я проверяю это, помещая точку останова в метод accept метода questionDao.getQuestions. Я полагаю, что работают два потока: один для заполнения, а второй - для получения вопросов.

Почему это происходит и как мне правильно это реализовать?

Заранее спасибо

1 Ответ

0 голосов
/ 07 января 2020

Я считаю, что следующие изменения будут работать

  1. Измените метод 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);

Когда вы вернете экземпляр в активность база данных будет заполнена.

...