zoukankan      html  css  js  c++  java
  • Android实战——RxJava2+Retrofit+RxBinding解锁各种新姿势

    本文已授权微信公众号:鸿洋(hongyangAndroid)原创首发。

    作为主流的第三方框架Rx系列,不学习也不行啊,对于初学者来说,可能RxJava看起来很难,用起来更难,但是你要知道,越复杂的东西往往能解决越复杂的问题,有可能你应用在项目中,也许你在面试的时候,就会和初级工程师拉开一大段距离。这门课程需要大家有Retrofit的基础,如果想学习Retrofit的同学可以查看我的博客,废话不多说,Hensen老师开车了。

    用原话就是:RxJava2是一个在Java虚拟机上,使用可观察的序列构成基于事件的,异步的程序库。不理解没关系,可以类比成我们的AsyncTask,这样就好理解多了

    RxJava传送门:https://github.com/ReactiveX/RxJava

    观察者模式就是RxJava使用的核心点,掌握这个模式,可以理解RxJava更简单,观察者模式简单的说就是”订阅-发布”的模式,举一例子说,当你订阅某家牛奶店的早餐奶(订阅过程),只要牛奶店生产牛奶,便会给你送过去(发布过程)。这里的牛奶店只有一家,但是订阅的人可以很多,这是一种一对多的关系,只要牛奶店发布牛奶,那么订阅的人就会收到牛奶。换做RxJava里面的话,牛奶店就是被观察者(Observable),订阅的人就是观察者(Observer)

    这里我们举一例子学校点名的例子,首先创建我们所说的观察者和被观察者

    各位可以思考一下,根据上面的介绍,学生和老师,谁是观察者,谁是被观察者,下面就看代码给你分析

    通过代码可以看到,注意分别实现的不同接口

    1、老师是被观察者,他需要实现接口的方法

    • 订阅/取消订阅:往集合中存放/移除观察者
    • 发布:循环遍历观察者,调用观察者方法

    2、学生是观察者,那么我们只需要给他个名字,实现观察者的方法即可

    最后,我们就把观察者和被观察者关联起来,LessonStart (上课啦)

    代码很简单,我们模拟了一个老师和小明同学和小红同学,老师已经知道看到两个人来了,那么可以开始点名了,下面通过Log打印出信息

    首先我先贴出我们后面所用到的第三方依赖库,以免后面忘记说了,大家对号入座

    其次还需要添加联网权限

    最后我们回到正题,看完上面的例子,我们可以知道RxJava就是这种订阅和发布的模式,换成我们的RxJava代码应该是怎么样的?当然也是通过被观察者订阅观察者啦

    我们具体被观察者和观察者的实现,当然是创建出来啦

    onNext方法就是我们的发布过程,我们看其观察者的创建就知道怎么回事了

    我们可以发现,观察者的创建实现的方法,在被观察者中是对应起来的,也就是说,我们发布了什么,就可以在观察者中收到订阅信息,那么我们就可以在代码中编写我们的逻辑了,这样基本上已经使用好了RxJava了,通过Log打印出信息

    1、人类就喜欢酷炫,炫耀,当然RxJava也少不了人类这种心理,就是链式编程,下面这段代码可以完美替代上面的所有代码

    这里我多写了两个方法,也就是.subscribeOn(Schedulers.io())和.observeOn(AndroidSchedulers.mainThread()),这里就是RxJava的好处之一,他可以手动切换线程,这两个方法在这里表示被观察者创建实现的方法都放在io线程也就是子线程,因为在被观察者中通常会调用网络数据请求,那么网络请求必须在子线程运行,当网络请求收到后,则发布出去,在观察者中通过TextView等控件展示在界面上,那么UI的更新必须在主线程进行,也就是我们上面的代码mainThread。如果你不深造RxJava,基本上这两个方法已经成了固定的写法,这也是很多初学者忘记添加上去的方法

    2、久而久之,人类喜欢简洁,喜欢定制服务,巧了,RxJava也给你满足了,下面这段代码中,实现的方法跟上面的实现方法是对应起来的,大家看参数就知道哪个对应哪个了,你可以通过new Consumer,不需要实现的方法你可以不写,看上去更简洁,这里我为了方便大家看,都new出来了,Consumer就是消费者的意思,可以理解为消费了onNext等等等事件

    哦,对了,我们还忘记打印Log信息,不能否认了我很帅这个事实

    当然你觉得只要夸奖我一个帅就行了,那么你也可以通过下面这几种方法发送给观察者

    这里的案例使用我们平时最简单的需求,看效果图就知道(图片会卡,效果大家脑补)

    这里写图片描述

    这里是整个代码的实现思路,我会在代码下面注释一下需要注意的点,代码我就直接贴出来,有句话说得好,成为大神,就必须先学会阅读别人的代码,哈哈哈,我的代码阅读起来应该没问题的吧

    1、操作符

    • 像这种interval、take、map、observeOn、doOnSubscribe、subscribe都是属于RxJava的操作符,简单的说就是实现某个方法,里面的功能都被包装起来了
    • RxJava支持的操作符很多,很多操作符用起来都简单,但是组合起来就很复杂,功能很强大,具体分类如图所示

    这里写图片描述

    2、操作符介绍

    • interval:延时几秒,每隔几秒开始执行
    • take:超过多少秒停止执行
    • map:类型转换,由于是倒计时,案例需要将倒计时的数字反过来
    • observeOn:在主线程运行
    • doOnSubscribe:在执行的过程中
    • subscribe:订阅

    RxJava与Retrofit的使用,更像我们的AsyncTask,通过网络获取数据然后通过Handler更新UI

    人类总是喜欢看图说话,巧了,我给你提供了,我只能拿出我过硬的美工技术给你们画图了

    这里写图片描述

    ① Bean对象

    • 这里我们采用的是httpbin的一个post接口,各位可以在它的网站试一下,这里的NetBean是通过请求返回的数据,进行GsonFormat生成的

    ② ApiService

    • 这里返回Observable对象,也就是我们RxJava的被观察者

    ③ RxJava+Retrofit的实现

    1、Retrofit

    • RxJava与Retrofit一起使用必须在Retrofit上加上这句话addCallAdapterFactory(RxJava2CallAdapterFactory.create())

    2、RxJava

    • 我们通过just方式发送数据
    • flatMap方法是用于数据格式转换的方法,其后面的参数UserParam与ObservableSource< NetBean>,参数一表示原数据,参数二表示转换的数据,那么就是通过发送网络参数,转换成网络返回的数据,调用Retrofit

    这个案例其实就是用户添加购物车的时候,首先会在本地存储一份,然后发现如果没有网络,那么没办法提交到服务器上,只能等下一次有网络的时候采用本地数据库和服务器数据的合并来实现上传到服务器,这里我们就贴RxJava与Retrofit的代码,不贴其他代码了,废话不多说,上图

    这里写图片描述

    这里使用到merge的操作符,其表示意思就是将两个ObservableSource合并为一个ObservableSource,最后的打印结果是

    RxBinding的使用也是为了让界面看起来更简洁,剩去了传统的findViewById和setOnClickListener的方法,不用任何声明,只要添加依赖就可以直接使用了

    这里的案例是说当我们在EditText打字实时搜索的时候,可能用户会打字很会快,中老年服装那么我们就没有必要一直发送网络请求,请求搜索结果,我们可以通过当用户打字停止后的延时500毫秒再发送搜索请求

    操作符

    • RxTextView.textChanges(edittext):Rxbinding用法
    • debounce:表示延时多少秒后执行
    • switchMap:也是数据转换,与flatMap的区别在注释中解释很清楚了

    演示效果图

    这里写图片描述

    这个案例很简单,当用户一直点击一个按钮的时候,我们不应该一直调用访问网络请求,而是 1秒内,只执行一次网络请求

    源码下载

    听说认真看的同学都会学的很多哦,对于RxJava的操作符还是建议大家通过官网的wiki去深造,回力只有当RxJava用在项目中的时候,你才会体会它的好处,同时也让你与初级工程师有了一定的距离,像很多RxBus、RxPermission、RxAndroid,很多人会疑问要不要去学习它,毫无疑问是必须学习的,技术是不断更新,只有当你的技术跟上时代的时候,你才有可能和大神聊的津津有味,以上纯属瞎掰,当然有时间我也会去学习Rx系列,如果喜欢我的朋友可以关注我的博客,或者加群大家一起学习吧

  • 相关阅读:
    python note 19 异常处理
    python note 18 序列化模块
    python note 17 random、time、sys、os模块
    python note 16 re模块的使用
    python note 15 正则表达式
    python note 13 内置函数
    python note 12 生成器、推导式
    C++ int型负数除法取余问题
    Leetcode162. 寻找峰值
    Leetcode450. 删除二叉搜索树中的节点
  • 原文地址:https://www.cnblogs.com/zhanglixina/p/9603747.html
Copyright © 2011-2022 走看看