Android и RxJava: вставить в базу данных Room модифицированный ответ

#android #rx-java #rx-java2

#Android #rx-java #rx-java2

Вопрос:

У меня есть два немного разных класса вопросов. Один из них — это модифицированный объект результатов вызова, а другой — объект Room @ в моем приложении для Android.

И теперь я хочу из моего класса Interactor class (прецедент) сделать следующее:

  1. Выполните вызов API и получите результат (список, в котором вопрос относится к модифицированному классу ответа)
  2. В случае успеха создайте новый игровой объект в базе данных my Room. Эта операция имеет long (идентификатор @Entity, который генерируется автоматически) в качестве возвращаемого типа.
  3. для каждого вопроса из модифицированного ответа (из (1)), question -> Конвертер, который преобразует retrofit.Question в database.Question. Метод конвертера принимает 2 параметра, объект retrofit.Question и идентификатор, который был возвращен на шаге (2). После преобразования добавьте в базу данных.
  4. Обратите внимание на AndroidSchedulers.mainthread. (subscribeOn вызывается из репозитория)

Теперь проблема, с которой я сталкиваюсь, заключается в создании этого потока с помощью RxJava из моего класса Interactor.

Вот все классы и вызовы. Сначала мой Interactor.class метод, который должен выполнять поток, описанный выше:

 public Single<List<Question>> getQuestionByCategoryMultiple(String parameter);
  

ВЫЗОВ API из MyAPI.class:

 //this Question is of database.Question.
Single<List<Question>> getQuestionByCategory(String parameter);
  

База данных Room repository.class:

 Single<Long> addGameReturnId(Game game);

Completable addQuestions(List<Question> questions);
  

Converter.class:

 public static List<database.Question> toDatabase(List<retrofit.Question> toConvert, int id);
  

У меня возникли проблемы с созданием потока, описанного выше, с помощью этих методов. Я попробовал сочетание .flatmap, .zip, .doOnSuccess и т.д. Без успешного создания потока.

Если вам нужно, чтобы я объяснил что-нибудь еще или лучше объяснил проблему, пожалуйста, прокомментируйте ниже.

public Single> getQuestionByCategoryMultiple(строковые параметры){

     return openTDBType
            .getQuestionByCategory(paramters)    //step 1
            // step 2
            // step 3
            .observeOn(AndroidSchedulers.mainThread());   //step 4

}
  

Редактировать:

Я пробовал что-то вроде этого:

 return openTDBType
                .getQuestionByCategory(parameters)
                .map(QuestionConverter::toDatabase)
                .flatMap(questions -> {
                    int id = gameRepositoryType.addGameReturnId(new Game(parameters).blockingGet().intValue();
                    questions.forEach(question -> question.setqId(id));
                    gameRepositoryType.addQuestions(questions);
                    return gameRepositoryType.getAllQuestions(); })
                .observeOn(AndroidSchedulers.mainThread());
  

^^ Я не знаю, лучший ли это способ сделать это? Кто-нибудь может подтвердить, является ли это хорошим способом разработки того, что я хочу здесь сделать, или если есть лучшие способы или какие-либо предложения?

Комментарии:

1. Я в замешательстве, почему Room DAO не предоставляет свои значения как Observable (или Flowable , в зависимости от того, что поддерживается).

2. @EpicPandaForce Не могли бы вы объяснить, что вы имеете в виду, я не совсем понимаю?

Ответ №1:

Старайтесь не использовать blockingGet , особенно когда этого можно избежать. Кроме того, addQuestions вообще не будет выполняться, потому что на него не подписаны. Вы можете добавить оба addGameReturnId и addQuestions в цепочку следующим образом:

 return openTDBType
            .getQuestionByCategory(parameters)
            .map(QuestionConverter::toDatabase)
            .flatMap(questions -> {
                return gameRepositoryType.addGameReturnId(new Game(parameters)) // returns Single<Long>
                    .map(id -> {
                        questions.forEach(question -> question.setqId(id));
                        return questions;
                    })      
            }) // returns Single<List<Question>> with the GameId attached
            .flatMapCompletable(questions -> gameRepositoryType.addQuestions(questions)) // returns Completable
            .andThen(gameRepositoryType.getAllQuestions()) // returns Single<>
            .observeOn(AndroidSchedulers.mainThread());
  

Комментарии:

1. Извините за поздний прием. Это было почти то, что мне было нужно, с flatMapCompletable(), являющимся ключом к построению моего потока. Спасибо!