【问题标题】:RxJava split one Observable to two subObservablesRxJava 将一个 Observable 拆分为两个 subObservable
【发布时间】:2015-12-21 09:31:05
【问题描述】:

我对@9​​87654321@ 完全陌生,我花了一整天的时间来理解它,我正在思考如何解决这个问题:

我有一个对象,由Retrofit 获取,它包含两个ArrayLists,我必须以不同的方式处理每个 ArrayList。目前它看起来像:

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

谢谢,
安东

【问题讨论】:

    标签: java android retrofit rx-java rx-android


    【解决方案1】:

    此答案适用于 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;
    }
    

    接下来,使用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 中的数据应用函数。有关详细信息,请参阅docs。在本例中,我们将创建两个流。 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);
        }
    });
    

    最后,确保你的 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(如果您还没有的话)。上面的 map 和 subscribe 代码,以及一般的 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); }
    );
    

    【讨论】:

    • 我很高兴你的回答比我需要的更清楚!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多