RxJava和Retrofit的介绍

2024-06-09 01:58
文章标签 java 介绍 retrofit rx

本文主要是介绍RxJava和Retrofit的介绍,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、ReactiveX简单介绍

Rx是一个使用可观察数据流进行异步编程的编程接口,ReactiveX结合了观察者模式、迭代器模式和函数式编程的精华。Rx提供了一系列的操作符,你可以使用它们来过滤(filter)、选择(select)、变换(transform)、结合(combine)和组合(compose)多个Observable,这些操作符让执行和复合变得非常高效。

在ReactiveX中,一个观察者(Observer)订阅一个可观察对象(Observable)。观察者对Observable发射的数据或数据序列作出响应。这种模式可以极大地简化并发操作,因为它创建了一个处于待命状态的观察者哨兵,在未来某个时刻响应Observable的通知,不需要阻塞等待Observable发射数据。

上图取自ReactiveX官方文档,上面一排图标代表被观察对象产生的事件,横向的箭头代表时间线,有6个事件依次发射,经过中间的转换和处理得到了下面的图标,即处理结果,有些事件发射、处理和接收都成功,而有些事件因为各种原因导致失败,这些情况都会在相应的回调方法中呈现。

Subscribe方法用于将观察者连接到Observable,你的观察者需要实现以下方法的一个子集:

  • onNext(T item)

    Observable调用这个方法发射数据,方法的参数就是Observable发射的数据,这个方法可能会被调用多次,取决于你的实现。

  • onError(Exception ex)

    当Observable遇到错误或者无法返回期望的数据时会调用这个方法,这个调用会终止Observable,后续不会再调用onNext和onCompleted,onError方法的参数是抛出的异常。

  • onComplete

    正常终止,如果没有遇到错误,Observable在最后一次调用onNext之后调用此方法。

根据Observable协议的定义,onNext可能会被调用零次或者很多次,最后会有一次onCompleted或onError调用(不会同时),传递数据给onNext通常被称作发射,onCompleted和onError被称作通知。

二、RxJava与RxAndroid的配合使用

RxJava是 ReactiveX 在JVM上的一个实现,ReactiveX使用Observable序列组合异步和基于事件的程序。RxJava提供了5种调度器,分别是:

  • .io()

    这个调度器时用于I/O操作。它基于根据需要,增长或缩减来自适应的线程池。由于它专用于I/O操作,所以并不是RxJava的默认方法;正确的使用它是由开发者决定的。重点需要注意的是线程池是无限制的,大量的I/O调度操作将创建许多个线程并占用内存。

  • .computation()

    这个是计算工作默认的调度器,它与I/O操作无关。它也是许多RxJava方法的默认调度器:buffer(), debounce(), delay() , interval(), sample(), skip()。

  • .immediate()

    这个调度器允许你立即在当前线程执行你指定的工作。它是timeout(),timeInterval(),以及timestamp()方法默认的调度器。

  • .newThread()

    这个调度器为指定任务启动一个新的线程。

  • .trampoline()

    当我们想在当前线程执行一个任务时,并不是立即,我们可以用.trampoline()将它入队。这个调度器将会处理它的队列并且按序运行队列中每一个任务。它是repeat()和retry()方法默认的调度器。

RxAndroid模块包含RxJava的Android特定的绑定代码。它给RxJava添加了一些类,用于帮助在Android应用中编写响应式(reactive)的组件。它提供了一个可以在给定的Android Handler上调度Observable的调度器 Scheduler,特别是在UI主线程上 AndroidSchedulers.mainThread()。

上面提到了几种线程调度器,可以让开发者在不同的线程执行不同的事件,那么如何指定和切换线程呢?RxJava提供了两个方法subscribeOn和observeOn,前者可以指定Observable事件产生和变换处理的线程,后者可以指定订阅者所在的线程,假如事件是一个耗时任务,完全可以通过subscribeOn指定为计算线程或者子线程,然后再通过observeOn切换Android主线程,即可在订阅者回调方法中操作UI视图。

看一个具体的例子吧。

Observable.just("").subscribeOn(Schedulers.newThread()).map(s -> {for (PerformanceEntity.Components components : performanceEntity.components) {PerformanceSubmitEntity.Data submitData = new PerformanceSubmitEntity.Data();submitData.componentId = components.id;for (PerformanceEntity.Data data : performanceEntity.data) {if (data.componentId == components.id) {transferData(submitData, data);break;}}submitDataList.add(submitData);}return null;}).observeOn(AndroidSchedulers.mainThread()).subscribe(o -> {initPerformanceView();});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

在渲染视图之前需要处理大量的数据,那么就可以将Observable的线程切换至子线程,等负责的业务逻辑完成后再切换至UI线程,然后在subscribe中完成视图的渲染。这样即可以保证UI线程不会大量复杂的计算,也可以不用Handler、AsycTask等复杂的操作,代码清晰度也相对较高。

三、RxJava与Retrofit的结合

在Android开发中,网络请求往往是最耗时的,也是情况最复杂的,如果直接在UI线程进行网络请求,编译时就会报错,及时编译报错,运行时系统也会报ANR错误,所以网络请求必须在子线程完成。而网络请求结果一般又需要操作UI视图,所以返回结果的回调有必须在主线程,那么上面提到的方法就可以完美解决这个问题。

网络请求的返回结果一般都是json格式,如果返回值为原始的字符串,那么就需要调用放每次都要进行json至JavaBean的转换,有的时候我们只关心返回结果中的一部分数据,那么就还需要在返回结果中再次对数据进行筛选,还有情况是我们只关心满足一定条件的数据,那么这些需求如果用RxJava来实现就变得异常简单。有关Retrofit详细用法,以及如何将返回结果切换成RxJava处理模式,可以阅读Retrofit用法详解这篇文章,下面直接看示例:

 showProgressBar();messageService.messageList(msgType, PAGE_INDEX, PAGE_SIZE).compose(new DefaultTransformer<>(getActivity())).map(messageListResponse -> messageListResponse.data).flatMap(messageListEntity -> Observable.from(messageListEntity)).filter(messageEntity.id > 10).subscribe(new Subscriber<MessageEntity>() {@Overridepublic void onCompleted() {dismissProgressBar();refreshLayout.setRefreshing(false);}@Overridepublic void onError(Throwable e) {dismissProgressBar();refreshLayout.setRefreshing(false);}@Overridepublic void onNext(MessageEntity messageEntity) {updateView(messageEntity);}});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • DefaultTransformer主要实现线程的切换以及错误消息的统一处理,一般来说服务端接口返回的数据格式都比较固定,会有code、message、data,其中code只是正确或者错误类型,message返回正确或者错误日志,data则是业务数据的存放地,那么就可以在DefaultTransformer中统一判断code值,如果是请求出错,那么直接将异常抛给onError回调方法。
  • map中实现的功能就是上文提到的调用方只关心data中的数据,而不关心code和message,那么就可以通过map方法直接将data中的数据传递给订阅者。
  • 如果我们想将返回值List逐条处理,一般的做法就是直接for循环,这里用到了flatMap,就是将messageListEntity通过Observable的from方法重新拆分成更细粒度的MessageEntity,而订阅者得到也就是MessageEntity。
  • filter方法就是通过布尔表达式筛选出符合条件的数据,上述例子中就是将id值大于10的MessageEntity筛选出来。

有关Observable的compose、map、from、flatMap、filter等方法可以参考ReactiveX官方教程,中文环境下可以参考给Android开发者的RxJava详解

这篇关于RxJava和Retrofit的介绍的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1043936

相关文章

Java程序进程起来了但是不打印日志的原因分析

《Java程序进程起来了但是不打印日志的原因分析》:本文主要介绍Java程序进程起来了但是不打印日志的原因分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java程序进程起来了但是不打印日志的原因1、日志配置问题2、日志文件权限问题3、日志文件路径问题4、程序

Spring 基于XML配置 bean管理 Bean-IOC的方法

《Spring基于XML配置bean管理Bean-IOC的方法》:本文主要介绍Spring基于XML配置bean管理Bean-IOC的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一... 目录一. spring学习的核心内容二. 基于 XML 配置 bean1. 通过类型来获取 bean2. 通过

Spring Boot 集成 Quartz并使用Cron 表达式实现定时任务

《SpringBoot集成Quartz并使用Cron表达式实现定时任务》本篇文章介绍了如何在SpringBoot中集成Quartz进行定时任务调度,并通过Cron表达式控制任务... 目录前言1. 添加 Quartz 依赖2. 创建 Quartz 任务3. 配置 Quartz 任务调度4. 启动 Sprin

springboot上传zip包并解压至服务器nginx目录方式

《springboot上传zip包并解压至服务器nginx目录方式》:本文主要介绍springboot上传zip包并解压至服务器nginx目录方式,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录springboot上传zip包并解压至服务器nginx目录1.首先需要引入zip相关jar包2.然

Java数组初始化的五种方式

《Java数组初始化的五种方式》数组是Java中最基础且常用的数据结构之一,其初始化方式多样且各具特点,本文详细讲解Java数组初始化的五种方式,分析其适用场景、优劣势对比及注意事项,帮助避免常见陷阱... 目录1. 静态初始化:简洁但固定代码示例核心特点适用场景注意事项2. 动态初始化:灵活但需手动管理代

Java使用SLF4J记录不同级别日志的示例详解

《Java使用SLF4J记录不同级别日志的示例详解》SLF4J是一个简单的日志门面,它允许在运行时选择不同的日志实现,这篇文章主要为大家详细介绍了如何使用SLF4J记录不同级别日志,感兴趣的可以了解下... 目录一、SLF4J简介二、添加依赖三、配置Logback四、记录不同级别的日志五、总结一、SLF4J

将Java项目提交到云服务器的流程步骤

《将Java项目提交到云服务器的流程步骤》所谓将项目提交到云服务器即将你的项目打成一个jar包然后提交到云服务器即可,因此我们需要准备服务器环境为:Linux+JDK+MariDB(MySQL)+Gi... 目录1. 安装 jdk1.1 查看 jdk 版本1.2 下载 jdk2. 安装 mariadb(my

SpringBoot中配置Redis连接池的完整指南

《SpringBoot中配置Redis连接池的完整指南》这篇文章主要为大家详细介绍了SpringBoot中配置Redis连接池的完整指南,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以... 目录一、添加依赖二、配置 Redis 连接池三、测试 Redis 操作四、完整示例代码(一)pom.

Java 正则表达式URL 匹配与源码全解析

《Java正则表达式URL匹配与源码全解析》在Web应用开发中,我们经常需要对URL进行格式验证,今天我们结合Java的Pattern和Matcher类,深入理解正则表达式在实际应用中... 目录1.正则表达式分解:2. 添加域名匹配 (2)3. 添加路径和查询参数匹配 (3) 4. 最终优化版本5.设计思

Java使用ANTLR4对Lua脚本语法校验详解

《Java使用ANTLR4对Lua脚本语法校验详解》ANTLR是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件,下面就跟随小编一起看看Java如何使用ANTLR4对Lua脚本... 目录什么是ANTLR?第一个例子ANTLR4 的工作流程Lua脚本语法校验准备一个Lua Gramm