Android RxJava 实战讲解:合并数据源 & 同时展示数据

原创 2017年11月06日 10:57:40

前言

  • Rxjava,由于其基于事件流的链式调用、逻辑简洁 & 使用简单的特点,深受各大 Android开发者的欢迎。

Github截图

如果还不了解RxJava,请看文章:Android:这是一篇 清晰 & 易懂的Rxjava 入门教程

  • RxJava如此受欢迎的原因,在于其提供了丰富 & 功能强大的操作符,几乎能完成所有的功能需求
  • 今天,我将为大家带来 Rxjava创建操作符的常见开发应用场景:合并数据源需求 ,并结合RetrofitRxJava 实现,希望大家会喜欢。
    1. 本系列文章主要基于 Rxjava 2.0
    2. 接下来的时间,我将持续推出 AndroidRxjava 2.0 的一系列文章,包括原理、操作符、应用场景、背压等等 ,有兴趣可以继续关注Carson_Ho的安卓开发笔记!!

示意图

目录

示意图


1. 需求场景

示意图


2. 功能说明

即,同时向2个数据源获取数据 -> 合并数据 -> 统一展示到客户端

3. 具体实现

此处采用` Merge()` & `Zip()`操作符进行讲解,其中:
  • Merge()例子 :实现较为简单的从(网络 + 本地)获取数据 & 统一展示
  • Zip()例子:结合RetrofitRxJava,实现较为复杂的合并2个网络请求向2个服务器获取数据 & 统一展示

3.1 采用 Merge()操作符

// 用于存放最终展示的数据
        String result = "数据源来自 = " ;

        /*
         * 设置第1个Observable:通过网络获取数据
         * 此处仅作网络请求的模拟
         **/
        Observable<String> network = Observable.just("网络");

        /*
         * 设置第2个Observable:通过本地文件获取数据
         * 此处仅作本地文件请求的模拟
         **/
        Observable<String> file = Observable.just("本地文件");


        /*
         * 通过merge()合并事件 & 同时发送事件
         **/
        Observable.merge(network, file)
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(String value) {
                        Log.d(TAG, "数据源有: "+ value  );
                        result += value + "+";
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    // 接收合并事件后,统一展示
                    @Override
                    public void onComplete() {
                        Log.d(TAG, "获取数据完成");
                        Log.d(TAG,  result  );
                    }
                });
  • 测试结果

示意图

3.2 采用Zip()操作符

关于操作符Zip() 的使用请看文章:Android RxJava:组合 / 合并操作符 详细教程

  • 功能说明
    在该例中,我将结合结合 RetrofitRxJava,实现:

    1. 从不同数据源(2个服务器)获取数据,即 合并网络请求的发送
    2. 统一显示结果
  • 实现方案
    采用Get方法 对 金山词霸API 发送2个网络请求(将英文翻译成中文,翻译2次) & 将2次翻译的结果一起显示。

采用 Gson 进行数据解析

金山词典

  • 步骤说明
    1. 添加依赖
    2. 创建 接收服务器返回数据 的类
    3. 创建 用于描述网络请求 的接口
    4. 创建 Retrofit 实例
    5. 创建 网络请求接口实例 并 配置网络请求参数
    6. 发送网络请求
    7. 发送网络请求
    8. 对返回的数据进行处理

本实例侧重于说明 RxJava 的线程控制,关于Retrofit的使用请看文章:这是一份很详细的 Retrofit 2.0 使用教程(含实例讲解)

  • 步骤实现
步骤1: 添加依赖

a. 在 Gradle加入Retrofit库的依赖

build.gradle

dependencies {

// Android 支持 Rxjava
// 此处一定要注意使用RxJava2的版本
compile 'io.reactivex.rxjava2:rxjava:2.0.1'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'

// Android 支持 Retrofit
compile 'com.squareup.retrofit2:retrofit:2.1.0'

// 衔接 Retrofit & RxJava
// 此处一定要注意使用RxJava2的版本
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'

// 支持Gson解析
compile 'com.squareup.retrofit2:converter-gson:2.1.0'

}

b. 添加 网络权限
AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET"/>
步骤2:创建 接收服务器返回数据 的类
  • 金山词霸API 的数据格式说明如下:
// URL模板
http://fy.iciba.com/ajax.php

// URL实例
http://fy.iciba.com/ajax.php?a=fy&f=auto&t=auto&w=hello%20world

// 参数说明:
// a:固定值 fy
// f:原文内容类型,日语取 ja,中文取 zh,英语取 en,韩语取 ko,德语取 de,西班牙语取 es,法语取 fr,自动则取 auto
// t:译文内容类型,日语取 ja,中文取 zh,英语取 en,韩语取 ko,德语取 de,西班牙语取 es,法语取 fr,自动则取 auto
// w:查询内容
  • 示例

API格式说明

  • 根据 金山词霸API 的数据格式,创建 接收服务器返回数据 的类:
    为了演示是两个网络请求,所以对应设置2个接收服务器的数据类
<-- Translation1.java -->
public class Translation1 {
    private int status;
    private content content;
    private static class content {
        private String from;
        private String to;
        private String vendor;
        private String out;
        private int errNo;
    }

   //定义 输出返回数据 的方法
    public String show() {

        return ("第1次翻译=" + content.out);

    }
}

<-- Translation2.java -->
public class Translation2 {
    private int status;
    private content content;
    private static class content {
        private String from;
        private String to;
        private String vendor;
        private String out;
        private int errNo;
    }

 //定义 输出返回数据 的方法
    public String show() {

        return ("第2次翻译=" + content.out);

    }
}
步骤3:创建 用于描述网络请求 的接口
采用 **注解** + `Observable
public interface GetRequest_Interface {

    // 网络请求1
    @GET("ajax.php?a=fy&f=auto&t=auto&w=hi%20world")
    Observable<Translation1> getCall();

    // 网络请求2
    @GET("ajax.php?a=fy&f=auto&t=auto&w=hi%20china")
    Observable<Translation2> getCall_2();

    // 注解里传入 网络请求 的部分URL地址
    // Retrofit把网络请求的URL分成了两部分:一部分放在Retrofit对象里,另一部分放在网络请求接口里
    // 如果接口里的url是一个完整的网址,那么放在Retrofit对象里的URL可以忽略
    // 采用Observable<...>接口
    // getCall()是接受网络请求数据的方法

}
接下来的步骤均在MainActivity.java内实现(请看注释)
*MainActivity.java*
public class MainActivity extends AppCompatActivity {


        private static final String TAG = "Rxjava";


        // 定义Observable接口类型的网络请求对象
        Observable<Translation1> observable1;
        Observable<Translation2> observable2;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            // 步骤1:创建Retrofit对象
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("http://fy.iciba.com/") // 设置 网络请求 Url
                    .addConverterFactory(GsonConverterFactory.create()) //设置使用Gson解析(记得加入依赖)
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 支持RxJava
                    .build();

            // 步骤2:创建 网络请求接口 的实例
            GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);

            // 步骤3:采用Observable<...>形式 对 2个网络请求 进行封装
            observable1 = request.getCall().subscribeOn(Schedulers.io()); // 新开线程进行网络请求1
            observable2 = request.getCall_2().subscribeOn(Schedulers.io());// 新开线程进行网络请求2
            // 即2个网络请求异步 & 同时发送

            // 步骤4:通过使用Zip()对两个网络请求进行合并再发送
            Observable.zip(observable1, observable2,
                    new BiFunction<Translation1, Translation2, String>() {
                        // 注:创建BiFunction对象传入的第3个参数 = 合并后数据的数据类型
                        @Override
                        public String apply(Translation1 translation1,
                                            Translation2 translation2) throws Exception {
                            return translation1.show() + " & " +translation2.show();
                        }
                    }).observeOn(AndroidSchedulers.mainThread()) // 在主线程接收 & 处理数据
                    .subscribe(new Consumer<String>() {
                        // 成功返回数据时调用
                        @Override
                        public void accept(String combine_infro) throws Exception {
                            // 结合显示2个网络请求的数据结果
                            Log.d(TAG, "最终接收到的数据是:" + combine_infro);
                        }
                    }, new Consumer<Throwable>() {
                        // 网络请求错误时调用
                        @Override
                        public void accept(Throwable throwable) throws Exception {
                            System.out.println("登录失败");
                        }
                    });
        }
}
  • 测试结果

示意图


4. 总结

  • 本文主要讲解了 Rxjava的实际开发需求场景:合并数据源需求 ,并结合RetrofitRxJava 实现
  • 下面我将结合 实际场景应用 & Rxjava的相关使用框架(如RetrofitEventbus ,继续对 AndroidRxjava 的实际开发需求场景进行深入讲解 ,有兴趣可以继续关注Carson_Ho的安卓开发笔记

示意图


请帮顶 / 评论点赞!因为你的鼓励是我写作的最大动力!

版权声明:本文为博主原创文章,未经博主允许不得转载,更多文章请继续关注Carson_Ho的博客!

RxJava 合并组合两个(或多个)Observable数据源

关键词:合并 Observable前言在RxJava中, 同时处理多个Observables是很常见的一种操作。下面我们简单分析下几个组合类的操作符。Merge在异步的世界经常会创建这样的场景,我们有...
  • jdsjlzx
  • jdsjlzx
  • 2016年09月02日 17:16
  • 29185

可能是东半球最全的RxJava使用场景小结

知道RxJava吗?这里罗列了东半球最全的RxJava使用场景哦,快来看看吧~
  • THEONE10211024
  • THEONE10211024
  • 2015年12月30日 16:31
  • 49472

RxJava—操作符(过滤、合并、转换)

RxJava—过滤、合并、转换,Observable的常用操作符讲述,提供免费demo下载。
  • aiyh0202
  • aiyh0202
  • 2016年12月07日 14:48
  • 2834

delphi函数参考手册

名称 类型 说明 abort 函数 引起放弃的意外处理 abs 函数 绝对值函数 addexitproc 函数 将一过程添加到运行时库的结束过程表中 addr 函数 返回指定对象的地址 adjustl...
  • icemanpro
  • icemanpro
  • 2002年01月29日 10:01
  • 982

rxjava+rxandroid+retrofit2.0使用方法demo讲解

最近看了retrofit框架,比较新的网络访问请求框架,很多项目都涉及到,所以学习了一下,做个总结。 第一讲 retrofit2.0单独使用 1、导入依赖jar包(也可能是library,反正st...
  • vae260772
  • vae260772
  • 2016年12月01日 14:51
  • 2246

Android 使用RxJava+Retrofit 2.0合并网络请求

在开发验证码的功能时,要求验证code的同时判断这个是不是服务码(万能码),这个就需要同时去请求两个接口,只要有一个功能就算成功。 @Override public void ch...
  • jasonwang18
  • jasonwang18
  • 2017年03月28日 16:07
  • 1635

Android RxJava+Retrofit 一次(合并)请求多个接口

在实际开发中,我们需要同时请求2个或者2个以上的接口,同时又有更新UI,怎么办呢?最直接的最暴力的方法就是直接在一个方法里同步调用两个接口,那使用RxJava怎么实现呢?这个问题可以使用RxJava的...
  • jdsjlzx
  • jdsjlzx
  • 2016年05月20日 22:26
  • 18011

Android RxJava 实战讲解:合并数据源 & 同时展示数据

前言 Rxjava,由于其基于事件流的链式调用、逻辑简洁 & 使用简单的特点,深受各大 Android开发者的欢迎。 如果还不了解RxJava,请看文章:Android:这是一篇 清晰 & 易懂的R...
  • carson_ho
  • carson_ho
  • 2017年11月06日 10:57
  • 4515

Android RxJava第一弹之原理详解、使用详解、常用场景(基于Rxjava2.0)

Android RxJava第一弹之原理详解、使用详解、常用场景(基于Rxjava2.0) Android RxJava第二弹之RxJava封装库 RxJava+Animation RxJava+...
  • qq_28195645
  • qq_28195645
  • 2016年09月17日 23:16
  • 4826

合并多个网络请求rxjava

在项目中出现要获取用户的三个部分的信息,决定在登录后直接全部获取保存在本地。 在学习rxjava中,发现有多种实现方式。 刚开始采用zip: flowable1,flowable2,flowab...
  • f1313131
  • f1313131
  • 2017年11月08日 10:27
  • 628
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android RxJava 实战讲解:合并数据源 & 同时展示数据
举报原因:
原因补充:

(最多只允许输入30个字)