简体   繁体   English

RxJava将一个Observable拆分为两个subObservable

[英]RxJava split one Observable to two subObservables

I'm totally new to RxJava and I've spent all day understanding it, I'm tying to think how to solve this problem: 我是RxJava ,我花了一整天时间来理解它,我很想思考如何解决这个问题:

I have one object, fetched by Retrofit , it contains two ArrayLists , I have to process every ArrayList differently. 我有一个由Retrofit提取的对象,它包含两个ArrayLists ,我必须以不同的方式处理每个ArrayList。 Currently it looks like: 目前它看起来像:

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

UPDATE: 更新:

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;
    }
}

Thanks, 谢谢,
Anton 安东

This answer is for Retrofit 2.0.0-beta, which is what you appear to be using. 这个答案适用于Retrofit 2.0.0-beta,这是你似乎正在使用的。 Also, you didn't give your POJO or service definitions, so going to use a general GitHub API example as a guide, modify to match your specify data. 此外,您没有提供POJO或服务定义,因此要使用常规GitHub API示例作为指南,修改以匹配您的指定数据。

First step is to convert your service definition to use Observable instead of Call . 第一步是将服务定义转换为使用Observable而不是Call

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

Where User is User在哪里

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

Next, add a custom call adapter with to your retrofit builder with addCallAdapterFactory -- 接下来,使用addCallAdapterFactory向您的改装构建器添加自定义调用适配器 -

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

Get your service in the usual way -- 以通常的方式获得您的服务 -

GitHubService gitHubService = retrofit.create(GitHubService.class);

Next, get your observable and call cache on it to create an Observable that will replay the result. 接下来,获取您的observable并在其上调用cache以创建将重放结果的Observable From that Observable, you can subscribe multiple times, in your case, you can subscribe twice. 从该Observable,您可以多次订阅,在您的情况下,您可以订阅两次。 Once for each type of data you are interested in, and use the map function to transform from the User object to your specific fields. 对于您感兴趣的每种类型的数据,使用map函数将User对象转换为特定字段。 map allows you to apply function to the data in the observable. map允许您将函数应用于observable中的数据。 See the docs for more details. 有关更多详细信息,请参阅文档 In this example, we will make two streams. 在这个例子中,我们将制作两个流。 One each for the id and login fields. idlogin字段各一个。

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

Finally, make sure your gradle file has the needed dependencies, 最后,确保您的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'

And, not directly related to your question, but if you are going to doing RxJava in Android, I recommend you checkout Retrolambda if you have not already. 并且,与您的问题没有直接关系,但如果您打算在Android中使用RxJava,我建议您查看Retrolambda(如果您还没有)。 The above map and subscribe code, and Rx code in general, is more succinct with lambdas. 上面的地图和订阅代码,以及一般的Rx代码,使用lambdas更简洁。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM