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>() {
                @Override
                public void onCompleted() {
                    dismissProgressBar();
                    refreshLayout.setRefreshing(false);
                }
                @Override
                public void onError(Throwable e) {
                    dismissProgressBar();
                    refreshLayout.setRefreshing(false);
                }
                @Override
                public 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详解

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: RxJavaRetrofit是一种经常结合使用的技术,主要是因为它们都能够协同工作,优化Android应用的性能。 具体而言,RxJava是一种响应式编程框架,可以通过异步数据流的方式处理数据。Retrofit则是一个RESTful框架,用于与服务器交互。因此,RxJava可以被用于处理从Retrofit返回的数据流。 这两个框架的结合使用可以让Android应用更快地处理数据并更好地应对网络请求。同时,通过使用RxJava的转换操作符,我们可以将从Retrofit返回的数据进行快速处理和转换。 ### 回答2: RXJava是一个响应式编程库,而Retrofit则是针对REST API进行网络请求和响应解析的框架。这两者结合使用,可以实现优雅的网络请求,并让代码更加简洁易懂。 Retrofit默认使用的是同步方法,这意味着如果在主线程中执行网络请求,就会阻塞主线程,造成卡顿甚至应用崩溃。为了避免这种情况,我们可以使用RXJava中的异步调度器,将网络请求放在IO线程中执行,并在请求完成后将结果回调到主线程中处理,保证应用的流畅性和响应性。 RXJava还提供了丰富的操作符,如map、filter、flatMap等,能够对网络请求的响应数据进行快速处理和转换,将数据转换成我们需要的格式,例如对象或列表。这样在显示数据时,可以节省大量的代码和时间。 另外,由于网络请求可能出现异常、网络超时等情况,我们需要对这些异常情况进行处理。RXJava提供了专门的异常处理操作符,如onErrorReturn、onErrorResumeNext等,能够快速捕获和处理网络请求异常,并在发生异常时执行相应的操作。 综上所述,RXJavaRetrofit的结合使用,能够方便地实现优雅的网络请求和数据处理,以及有效地解决网络请求可能出现的异常情况,为开发者提供了更加便捷、高效、安全的开发体验。 ### 回答3: RxJavaRetrofit是目前Android开发中非常流行的两个库。他们都不是新兴的库,RxJava是由Netflix公司开发的响应式编程库,是在Java Future的基础上进行开发的。Retrofit是由Square公司开发的网络请求库。在进行Android开发时,我们一般会经常使用Retrofit来完成网络请求的操作,而配合使用RxJava可以让我们更加方便的处理网络请求的结果。 为什么要使用RxJavaRetrofitRetrofit是一个基于OkHttp的RESTful API请求框架,可以让我们通过定义相应的接口,来进行网络请求,使用简单而且很快,这也是为什么它会被Android开发者广泛使用的原因。而RxJava则是将异步事件组合在一起的响应式编程库,可以让我们以响应式的方式来处理网络请求的结果。因此,当我们结合使用这两个库时,就可以更加高效地完成Android的开发。 如何使用RxJavaRetrofit? 使用RxJavaRetrofit大致的流程如下: 1. 在build.gradle文件中添加RetrofitRxJava的依赖: ``` implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'io.reactivex.rxjava2:rxjava:2.2.19' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' ``` 2. 定义Retrofit接口: ``` public interface ApiService { @GET("users") Observable<List<User>> getUsers(); } ``` 3. 使用RetrofitRxJava进行网络请求: ``` ApiService apiService = RetrofitClient.getInstance().create(ApiService.class); apiService.getUsers() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<List<User>>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(List<User> users) { // 成功获取到用户列表 } @Override public void onError(Throwable e) { // 网络请求失败 } @Override public void onComplete() { } }); ``` 在这个示例中,我们首先定义了一个ApiService接口,其中包含了我们需要进行网络请求的方法。在进行网络请求时,我们可以使用Retrofit的create()方法来实例化一个ApiService对象,然后使用subscribeOn()和observeOn()方法进行线程调度,最后使用subscribe()方法订阅Observer对象,即可完成网络请求的操作。 结论 RxJavaRetrofit可以很好地配合使用,使我们可以简洁、高效地处理网络请求的结果。配合使用可以大大提高我们的开发效率,同时也可以减少我们的代码量,让我们可以更加专注于业务逻辑的实现。因此,在进行Android开发时,建议使用这两个库来完成网络请求的操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值