Android RxJava实际应用案例讲解:使用RxJava的最佳开发场景

原创 2018年01月26日 09:27:40

前言

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

Github截图

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

  • 今天,我将为大家带来 Rxjava的的基本使用 & 实际应用案例教学,即常见开发应用场景实现 ,并结合常用相关框架如Retrofit等,希望大家会喜欢。
    1. 本系列文章主要基于 Rxjava 2.0
    2. 接下来的时间,我将持续推出 AndroidRxjava 2.0 的一系列文章,包括原理、操作符、应用场景、背压等等 ,有兴趣可以继续关注Carson_Ho的安卓开发笔记!!

示意图

目录

示意图


1. 简介

RxJava的简介如下

示意图


2. 基本使用


3. 实际开发应用场景

  • RxJava的实际开发应用场景 与 其对应的操作符息息相关
  • 常见的RxJava实际开发应用场景有如下:

示意图

  • 下面,我将对每个实际开发应用场景进行实例讲解教学
    下面实例皆结合常用框架如RetrofitRxBindingRxBus

3.1 网络请求轮询(无条件)


3.2 网路请求轮询(有条件)


3.3 网络请求出错重连

  • 需求场景
    示意图

  • 功能需求说明

示意图

  • 功能逻辑

示意图

3.4 网络请求嵌套回调

  • 背景
    需要进行嵌套网络请求:即在第1个网络请求成功后,继续再进行一次网络请求

    如 先进行 用户注册 的网络请求, 待注册成功后回再继续发送 用户登录 的网络请求

  • 冲突
    嵌套实现网络请求较为复杂,即嵌套调用函数

    下面展示的是结合 RetrofitRxJava的基本用法,即未用操作符前

// 发送注册网络请求的函数方法
    private void register() {
        api.register(new RegisterRequest())
                .subscribeOn(Schedulers.io())               //在IO线程进行网络请求
                .observeOn(AndroidSchedulers.mainThread())  //回到主线程去处理请求结果
                .subscribe(new Consumer<RegisterResponse>() {
                    @Override
                    public void accept(RegisterResponse registerResponse) throws Exception {
                        Toast.makeText(MainActivity.this, "注册成功", Toast.LENGTH_SHORT).show();
                        login();   //注册成功, 调用登录的方法
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        Toast.makeText(MainActivity.this, "注册失败", Toast.LENGTH_SHORT).show();
                    }
                });
    }


// 发送登录网络请求的函数方法
private void login() {
        api.login(new LoginRequest())
                .subscribeOn(Schedulers.io())               //在IO线程进行网络请求
                .observeOn(AndroidSchedulers.mainThread())  //回到主线程去处理请求结果
                .subscribe(new Consumer<LoginResponse>() {
                    @Override
                    public void accept(LoginResponse loginResponse) throws Exception {
                        Toast.makeText(MainActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        Toast.makeText(MainActivity.this, "登录失败", Toast.LENGTH_SHORT).show();
                    }
                });
    }

3.5 从磁盘 / 内存缓存中 获取缓存数据


3.6 合并数据源

  • 需求场景

示意图


3.7 联合判断

  • 需求场景
    需要同时对多个事件进行联合判断

    如,填写表单时,需要表单里所有信息(姓名、年龄、职业等)都被填写后,才允许点击 “提交” 按钮

  • 功能说明
    此处采用 填写表单 作为联合判断功能展示,即,表单里所有信息(姓名、年龄、职业等)都被填写后,才允许点击 “提交” 按钮

  • 具体实现
    Android RxJava 实际应用讲解:联合判断


3.8 线程控制(切换 / 调度 )


3.9 功能防抖

  • 需求场景
    示意图

  • 功能说明

示意图


3.10 联想搜索优化

  • 需求场景
    示意图

  • 功能说明

示意图


3.11 控制被观察者发送事件 & 观察者接收事件速度:背压

a. 背景

  • 观察者 & 被观察者 之间存在2种订阅关系:同步 & 异步。具体如下:

示意图

  • 对于异步订阅关系,存在 被观察者发送事件速度 与观察者接收事件速度 不匹配的情况
    1. 发送 & 接收事件速度 = 单位时间内 发送&接收事件的数量
    2. 大多数情况,主要是 被观察者发送事件速度 > 观察者接收事件速度

b. 冲突
  • 被观察者 发送事件速度太快,而观察者 来不及接收所有事件,从而导致观察者无法及时响应 / 处理所有发送过来事件的问题,最终导致缓存区溢出、事件丢失 & OOM
  • 如,点击按钮事件:连续过快的点击按钮10次,则只会造成点击2次的效果;
  • 解释:因为点击速度太快了,所以按钮来不及响应
  • 下面再举个例子:
    • 被观察者的发送事件速度 = 10ms / 个
    • 观察者的接收事件速度 = 5s / 个

    即出现发送 & 接收事件严重不匹配的问题

     Observable.create(new ObservableOnSubscribe<Integer>() {
                // 1. 创建被观察者 & 生产事件
                @Override
                public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
    
                    for (int i = 0; ; i++) {
                        Log.d(TAG, "发送了事件"+ i );
                        Thread.sleep(10);
                        // 发送事件速度:10ms / 个 
                        emitter.onNext(i);
    
                    }
    
                }
            }).subscribeOn(Schedulers.io()) // 设置被观察者在io线程中进行
                    .observeOn(AndroidSchedulers.mainThread()) // 设置观察者在主线程中进行
                 .subscribe(new Observer<Integer>() {
                // 2. 通过通过订阅(subscribe)连接观察者和被观察者
    
                @Override
                public void onSubscribe(Disposable d) {
                    Log.d(TAG, "开始采用subscribe连接");
                }
    
                @Override
                public void onNext(Integer value) {
    
                    try {
                        // 接收事件速度:5s / 个 
                        Thread.sleep(5000);
                        Log.d(TAG, "接收到了事件"+ value  );
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
    
                }
    
                @Override
                public void onError(Throwable e) {
                    Log.d(TAG, "对Error事件作出响应");
                }
    
                @Override
                public void onComplete() {
                    Log.d(TAG, "对Complete事件作出响应");
                }
    
            });
    • 结果
      由于被观察者发送事件速度 > 观察者接收事件速度,所以出现流速不匹配问题,从而导致OOM
      示意图

    c. 解决方案
    采用 背压策略

    至此,关于RxJava常见的实际开发应用场景讲解完毕。


    4. 总结

    • 本文主要对 RxJava2 中常用的实际开发应用场景讲解进行了详细介绍,下面用1张图进行总结

    示意图

    • 接下来,我将持续推出 AndroidRxjava 2.0 的一系列文章,包括原理、操作符、应用场景、背压等等 ,有兴趣可以继续关注Carson_Ho的安卓开发笔记!!

    示意图


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

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

    Android RxJava实际应用案例讲解:使用RxJava的最佳开发场景

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

    RxJava + Retrofit 的实际应用场景

    前提需要知道什么是 RxJava 这里推荐下 扔物线写的 给 Android 开发者的 RxJava 详解 再感谢 RxJava 与 Retrofit 结合的最佳实践 这篇满满的干货。实战准备项目...
    • jdsjlzx
    • jdsjlzx
    • 2016年05月24日 21:43
    • 2131

    RxJava在Android中使用场景详解

    在Android开发中的一些真实场景如何使用RxJava
    • johnny901114
    • johnny901114
    • 2016年04月02日 10:17
    • 2820

    了解RxJava以及如何在Android应用中使用它

    如果你在阅读这篇文章,相信你一定很想了解RxJava以及如何在Android应用中使用它。可能你已经见过RxJava的代码了,但仍然有些疑惑,愿你能在这篇文章里找到答案。 当我第一次使用RxJa...
    • xjbclz
    • xjbclz
    • 2016年11月13日 19:55
    • 2210

    RxJava使用场景小结

    取数据先检查缓存的场景取数据,首先检查内存是否有缓存 然后检查文件缓存中是否有 最后才从网络中取 前面任何一个条件满足,就不会执行后面的final Observable memory = ...
    • lzyzsd
    • lzyzsd
    • 2015年11月30日 23:16
    • 44329

    安卓开发进阶之RxJava在实际项目中使用--第二篇

    关于RxJava原理分析,请参考仍物线写的文章—-给 Android 开发者的 RxJava 详解。本文不对原理作过多的分析,从最快上手的角度,让开发者使用起来,当我们有实践经验后回过头来看原理分析会...
    • zhangxiangliang2
    • zhangxiangliang2
    • 2017年07月02日 16:26
    • 1514

    RxJava RxAndroid 在android中最重要的应用(一)

    首先 在这里放上两个库的地址 https://github.com/ReactiveX/RxJava https://github.com/ReactiveX/RxAndroid   在andro...
    • ccj659
    • ccj659
    • 2016年05月03日 17:17
    • 1094

    Android RxJava实际应用案例讲解:使用RxJava的最佳开发场景

    前言 Rxjava由于其基于事件流的链式调用、逻辑简洁 & 使用简单的特点,深受各大 Android开发者的欢迎。 如果还不了解RxJava,请看文章:Android:这是一篇...
    • fengyeNom1
    • fengyeNom1
    • 2018年01月27日 16:37
    • 29

    Android使用RxJava浅析

    首先说一下自己为什么使用到了RxJava,因为在处理网络异步数据的时候,我一般是使用Thread+Handler或者AsyncTask来实现,直到接触了RxJava后,竟然可以如此便利的进行网络请求以...
    • csdn_eric_zhao
    • csdn_eric_zhao
    • 2016年09月29日 14:09
    • 93

    RxJava在Android的应用场景

    导入//rxjava compile 'io.reactivex:rxjava:latest.release' //rxAndroid compile 'io.reactivex:rxandroid:...
    • a1018875550
    • a1018875550
    • 2016年10月08日 14:18
    • 1147
    内容举报
    返回顶部
    收藏助手
    不良信息举报
    您举报文章:Android RxJava实际应用案例讲解:使用RxJava的最佳开发场景
    举报原因:
    原因补充:

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