我试图从使用普通Retrofit迁移到使用RxJava扩展进行改造,以便在后台线程上进行API调用链。

例如,我有一个名为ModelGroup的对象,该对象具有ModelPerson对象的列表。我的目标是执行以下操作。


将ModelGroup发送到服务器并接收响应,该响应是一个整数,代表新插入的ID,我们将其称为newGroupId。
对于ModelGroup中的每个ModelPerson,将Person.groupId设置为newGroupId。
将每个人发送到服务器。
如果使用newGroupId成功更新了ModelGroup中的所有ModelPerson对象,则使用onSuccess响应,否则使用onError响应。


我当前的解决方案如下所示。

private void makeGroupInsert(ModelGroup modelGroup) {

    int newGroupId = myApi.insertNewGroup(modelGroup.getName(), modelGroup.getRating())
            .execute()
            .body();

    for (ModelPerson person : modelGroup.getPersons()) {
        person.setGroupId(newGroupId);

        String response = myApi.insertNewPerson(
                person.getGroup_id(),
                person.getFirst_Name(),
                person.getLast_Name())
                .execute()
                .body();

        if (!response.equals("success")) {
            // One failed to update, send error to main thread.
        }
    }

    // All succeeded, send success back to main thread.
}




如何使用RxJava + Retrofit解决方案实现相同(或更好)的功能?

编辑1

MyApi在下面定义。

public interface MyApi {

    @POST("insert_new_group")
    Call<Integer> insertNewGroup(@Query("group_name") String groupName,
                                   @Query("group_rating") int rating);

    @POST("insert_new_person")
    Call<String> insertNewPerson(@Query("group_id") int groupId,
                                   @Query("first_name") String firstName,
                                   @Query("last_name") String lastName);
}

最佳答案

首先,您需要更改Retrofit bean以使用Observables。例如,它看起来像下面的行:

@POST("insert_new_group")
Observable<Integer> insertNewGroup(...


然后,您可以链接请求:

void updateData() {
    myApi.insertNewGroup(modelGroup.getName(), modelGroup.getRating()) //Creating new group and getting its ID
            .switchMap(this::setGroupIdAll) //Calling observable that will loop thru all persons and set their groupIDs
            .subscribe(
                    (n) -> {/*you will get String after every 'insertNewPerson' run*/},
                    (e) -> {/*error handling*/}
            );

}

Observable<String> setGroupIdAll(Integer id) {
    return Observable.fromIterable(personsIterable) //personsIterable contains all your ModelPerson objects
            .flatMap(this::updatePerson); //Call Observabl;e that will send updated person to the server
}

Observable<String> updatePerson(ModelPerson person) {
    return myApi.insertNewPerson(
            person.getGroup_id(),
            person.getFirst_Name(),
            person.getLast_Name());
}

07-27 20:27