• RxJava简单的介绍


    1. RxJava简介

    Rx(ReactiveX,响应式编程)是一种事件驱动的基于异步数据流的编程模式,整个数据流就像一条河流,它可以被观测(监听),过滤,操控或者与其他数据流合并为一条新的数据流。而RxJava是.Net Rx在JVM上的实现。RxJava可以应用于大部分基于JVM的语言,如Scala,Groovy等。整个RxJava+RxAndroid的包大小为(1125kb+10kb)

    2.RxJava特点

    • 函数响应式编程(Functional Reactive Programming,FRP)
    • 异步
    • 事件驱动的
    • 基于观察者模式
    • 专门的出错处理,当使用RxJava出现错误时,它不会直接抛出异常,而是会执行OnError()方法;
    • 并发,可以很容易实现多线程

    3.RxJava的基本概念

    RxJava最核心的两个东西是Observables(被观察者,事件源)和Subscribers(观察者),Observables发出一系列事件,Subscribers处理这些事件。而RxJavaObservables是扩展自设计模式中的观察者模式,添加了以下几个能力:

    • onCompleted(),当没有新的可用数据时,通知Observables
    • onError(),当发生错误时,通知Observables,但不会直接将错误或异常直接抛出;

    3.1 四个关键概念

    • Observable,产生事件(事件源)
    • Observer, 根据事件作出相应的响应
    • Subscriber,实现了Observer的抽象类,
    • Subjects,Observable + Observer

    3.1.1 Observable

    Observable在存活期间,生命周期包含三个可能的事件,与迭代器的生命周期很类似:

    Events Iterable(pull) Observable(push)
    得到数据 T next() onNext(T)
    发现错误 throws Exception onError(Throwable)
    完成 !hasNext() onCompleted()

    与使用迭代器的区别:在使用迭代器的时候,线程会阻塞直到他们需要的数据到来。而使用Observable,是使用异步的方式将数据推送到Observer;

    而根据推送机制的不同,Observable分为热Observable和冷Observable:

    • 热Observable,当他创建时新开始执行它的职责,这样所有订阅了这个Observable的Observer就可以直接大中途观察了(但可能会丢失前面发送的数据(事件));
    • 冷Observable,只有等到有订阅(subscribes)了这个Observable的Observer才开始执行它的职责:发送数据;

    下面是一个简单的创建观察者的代码:

    Observable.create(new Observable.OnSubscribe<Object>(){
    @Override
    public void call(Subscriber<? super Object> subscriber){}
    });
    
    // example
    Observable<Integer> ob=
    Observable.create(new Observable.OnSubscribe<Integer>(){
    @Override
    public void call(Subscriber<? super Integer> subscriber){
    for(int i = 0; i < 5; i++){
    observer.onNext(i);
    }
    observer.onCompleted();
    }
    });
    // 并不用关心有多少数据,
    Subscription subscriptionPrint = 
     observableString.subscribe(new Observer<Integer(){
     @Override
     public void onCompleted(){
     System.out.println("Observable completed");
     }
      @Override
     public void onError(Throwable e){
      System.out.println("Oh no! Something wrong happened!");
     }
     
      @Override
     public void onNext(Integer item)
        System.out.println("Item is " + item); 
     })
    

    Observable的构造方法:

    • create(subscribe),需要一个subscribe作为参数来构造,
    • from(list)// 用来从一个已知的列表的产生数据,和前面的create作用类似;
    • just(funnction),用来接收从一个方法的返回值(最多可以有9个参数),如果返回的是List,它不会去逐个遍历List的Items,而是直接输出整个List ;
    • empty(),不输出数据,但可以正常结束;
    • never(),不输出数据,并且不会终止;
    • throw(),不输出数据,但在发生错误时终止;
    • interval(),创建一个按固定间隔发送整数序列的Observable,
    • timer(),创建一个Observable在给定的延迟后发送一个特殊的值;

    3.1.2 Subject

    Subject = Observable + Observer
    这意味着一个Subject可以同时是观察者和被观察者,事件源(Observable),也就是说Subject可以像观察者一样订阅一个事件源,并且可以像Observable一样输出它们收到的事件。RxJava提供了四种不同类型的subjects:

    • PublishSubject,
    • BehaviorSubject,输出它观察到的大部分最近的Items和随后观察的Items到所有的订阅者,初始化时需要一个初始值来做为最近的Items
    • ReplaySubject,将它观察到的所有数据重复发送到所有订阅了的观察者;
    • AsyncSubject, 在整个Observable完成后,将最后观察到的Items发送给每一个订阅者;

    4. RxJava的操作符

    4.1 过滤

    • filter(),过滤掉不需要的数据,只有返回true 的数据才会被使用;
    • take(int n),只取返回数据中的前n个,skip(int n)跳过前n个数据;
    • takeLast(int n),只取数据的最后n个,skipLast(int n);
    • distinct(),会帮助我们处理重复的数据,但如果数据太大的话,内存需要比较大
    • distinctUntilChanged(),只有当新数据与先前的不同,才会输出,
    • first(),last();
    • firstOrDefault(),lastOrDefault,如果Observable没有输出任何数据时,我们可以给一个默认值;
    • elementAt(int n),输出第n个位置上的数据(从0 开始)
    • timeout(),如果在给定时间间隔内,没有输出有效数据,则会执行onError();
    • delay() 用于事件流中,延迟一段时间再发送来自Observable的结果;

    4.2 映射

    • map(),用来映射简单的数据
    • flatMap(),用来映射队列等,但可能会改变数据的顺序
    • concatMap(),解决了fmp的交错的问题
    • flatMapIterable(),将生成的Iterable与Items进行对应起来(类似于key-value);
    • switchMap(),
      这几个方法都是将输入的数据以一种新的形式输出;
    • Scan(),类似于一个累加的方法,后一个item是前面item的后再加上原来的item;
    • GroupBy(),
    • buffer(int n),将数据作为列表(每n个数据作为一个列表)输出而不是单个的Items;
    • cast() 类似于map();

    4.3 合并

    • merge()可以将多个输入整合成一个输出(并不会合并Items);
    • zip(),可以将多个输入整合成一个输出(会合并Items);

    4.3 重试

    • retryWhen(),当接收到onError()事件时,触发重新订阅(发生某些错误时,需要做什么工作);
    • repeat(),当接收到onComplete()事件时,触发重新订阅

    4.4 线程的调度(Schedulers)

    RxJava提供了5种类型的调度者:
    Schedulers

    • .io(), 使用线程池来为IO操作进行调度,但没有骑士线程池的大小 作限制,因此使用时需要考虑内存的使用
    • .computation(),与IO无关的计算型调度,有很多RxJava相关的默认方法:buffer(),debounce(),delay(),interval()等默认是在该类线程中执行;
    • .immediate(),在当前线程中快速开始某项操作,是方法:timeout(),timeInterval等的默认调度器;
    • .newThread(), 开启新线程来执行某项操作
    • .trampoline(),为一些不需要立即执行的任务进行调度,会依次执行队列里的任务,是方法:repeat(),retry()的默认调度器;

    RxAndroid还提供了一个Android特有的调度器:AndroidSchedulers.mainThread()来让代码在UI主线程中执行;

    RxJava提供了一个每一个Observables都可以使用的subscribeOn(),ObserveOn()方法,将Scheduler与Observables建立联系,我们可以这样来使用:

    .subscribeOn(Schedulers.io())  // 让事件的产生发生在IO线程,多次调用,以最后一次调用的结果为准
    .observeOn(AndroidSchedulers.mainThread()) // 让事件的回调发生在UI主线程中
    .subscribe(....)
    

    5. RxAndroid

    前面版本的RxAndroid还提供了AppObservable,ViewObservable,WidgetObservable,LifecycleObservable 等,但最新版本的RxAndroid直接删掉了这些;

    相关的使用例子可参考这个,也可以参考我写的 小Demo

    6.参考文献:

    1
    Grokking RxJava,Part 4
    RxJava处理网络失败
    RxJava Essentials
    给Android开发者的RxJava详解
    拆RxJava

  • 相关阅读:
    tomcat的systemctl启动脚本
    vmware中虚拟化的问题
    zabbix-3.4.14源码安装
    tomcat启动后8005端口未被占用
    Centos7初始化脚本
    CentOS7.3上如何安装Apache/2.4.34
    js完整教程一 : 基本概念和数组操作
    浅入浅出Lambda表达式
    这些基础却重要的面向对象概念,你还记得多少
    MVC5+EF6 入门完整教程11--细说MVC中仓储模式的应用
  • 原文地址:https://www.cnblogs.com/WoodJim/p/5970937.html
Copyright © 2020-2023  润新知