Android 和 RxJava:将 Retrofit Response 插入到 Room 数据库中

Android and RxJava: insert into Room database a Retrofit Response

我有两个略有不同的问题 classes。一个是改装调用结果对象,另一个是我的 Android App.

中的 Room @Entity

现在我想从我的交互器 class(用例)class 中执行以下操作:

  1. 调用 API 和结果(列出问题所在 改造响应 class)
  2. 成功后,在我的 Room 数据库中创建一个新的 Game 对象。此操作有很长(自动生成的@Entity id)为return 类型。
  3. 对于来自改造响应(来自(1))的每个问题,问题 -> 从 retrofit.Question 转换为的转换器 database.Question。转换器方法需要 2 个参数, retrofit.Question 对象和在步骤 (2) 中 return 编辑的 ID。 转换后,添加到数据库。
  4. 观察AndroidSchedulers.mainthread。 (从存储库调用 subscribeOn)

现在我遇到的问题是从我的 Interactor class.

使用 RxJava 创建这个流

这里是所有 classes 和调用。首先是我的 Interactor.class 方法,它应该执行上述流:

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

来自 MyAPI.class 的 API 呼叫:

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

房间数据库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());

^^ 我不知道这是否是解决此问题的最佳方法?任何人都可以确认这是否是设计我想在这里做的事情的好方法,或者是否有更好的方法或任何建议?

尽量不要使用 blockingGet,尤其是在可以避免的情况下。另外,addQuestions 根本不会执行,因为它没有被订阅。您可以像这样将 addGameReturnIdaddQuestions 添加到链中:

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());