RxJava将一个Observable分裂成两个子Observable

4

我完全不了解 RxJava,今天一整天都在学习它,现在我在考虑如何解决这个问题:

我有一个由 Retrofit 获取的对象,其中包含两个 ArrayLists,我需要分别处理每个列表。目前的情况是:

apiService.getUser(token).enqueue(new Callback<User>() {
            @Override
            public void onResponse(Response<User> response) {

                final User user = response.body();

                for (Skill s : user.getSkills()) {
                    // process here first ArrayList
                }

                for (OrganizerAction o : user.getOrganizerActions()) {
                    // process here second ArrayList
                }
            }

            @Override
            public void onFailure(Throwable t) {
                t.printStackTrace();
            }
        });

更新:

public class User {

    // fields

    @SerializedName("organizer_actions")
    @Expose
    private List<OrganizerAction> mOrganizerActions;

    @SerializedName("skills")
    @Expose
    private List<Skill> mSkills;

    public List<OrganizerAction> getOrganizerActions() {
        return mOrganizerActions;
    }

    public List<Skill> getSkills() {
        return mSkills;
    }
}

谢谢,
安东

1个回答

5
这篇答案是针对Retrofit 2.0.0-beta的,这也是您现在使用的版本。同时,由于您没有提供POJO或服务定义,因此我们将使用一个通用的GitHub API示例作为指南,并进行修改以匹配您特定的数据。

第一步是将您的服务定义转换为使用Observable而不是Call

public interface GitHubService {
    @GET("/users/{user}")
    Observable<User> getUser(@Path("user") String user);
}

其中User

public class User {
    public String login;
    public int id;
}

接下来,在你的retrofit构建器中使用addCallAdapterFactory添加一个自定义调用适配器--

Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://api.github.com/")
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .build();

以通常方式获取您的服务--
GitHubService gitHubService = retrofit.create(GitHubService.class);

接下来,获取您的observable并在其上调用cache以创建将重放结果的Observable。 从该Observable中,您可以多次订阅,在您的情况下,您可以订阅两次。一次用于您感兴趣的每种数据类型,并使用map函数从User对象转换为您的特定字段。map允许您将函数应用于observable中的数据。有关更多详细信息,请参见文档。在此示例中,我们将创建两个流。一个流用于id字段,另一个流用于login字段。
Observable<User> getUserResult = gitHubService.getUser("octocat").cache(1);

getUserResult.map(new Func1<User, Integer>() {
    @Override
    public Integer call(User user) {
        return user.id;
    }
}).subscribe(new Action1<Integer>() {
    @Override
    public void call(Integer id) {
        Log.d("Stream 1", "id = " + id);
    }
});

getUserResult.map(new Func1<User, String>() {
    @Override
    public String call(User user) {
       return user.login;
    }
}).subscribe(new Action1<String>() {
    @Override
    public void call(String login) {
        Log.d("Stream 2", "login = " + login);
    }
});

最后,请确保您的gradle文件具有所需的依赖项。
compile 'io.reactivex:rxjava:1.0.14'
compile 'com.squareup.retrofit:retrofit:2.0.0-beta1'
compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta1'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta1'

并且,虽然这与您的问题没有直接关系,但如果您想在Android上使用RxJava,我建议您查看Retrolambda。以上的地图和订阅代码以及Rx代码通常都更加简洁明了。

getUserResult.map(user -> user.id).subscribe(
        id -> { Log.d("Stream 1", "id = " + id); }
);

getUserResult.map(user -> user.login).subscribe(
        login -> { Log.d("Stream 2", "login = " + login); }
);

我非常高兴,你的回答甚至比我需要的还要清晰! - Anton Shkurenko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接