Rxjava 简单使用及源码分析

1.简介

Rxjava由于其基于事件流的链式调用、逻辑简洁 & 使用简单的特点,深受各大 Android开发者的欢迎,RxJava2是非常好用的一个异步链式库. RxAndroid是RxJava的一个针对Android平台的扩展,主要用于 Android 开发.

RxJava:a library for composing asynchronous and event-based programs using observable sequences for the Java VM// 翻译:RxJava 是一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库总结:RxJava 是一个 基于事件流、实现异步操作的库

特点:类似于 Android中的 AsyncTask 、Handler作用 基于事件流的链式调用,所以使得 RxJava:逻辑简洁实现优雅使用简单更重要的是,随着程序逻辑的复杂性提高,它依然能够保持简洁 & 优雅

2.观察者模式

生活例子引入我用一个生活例子引入 & 讲解 Rxjava原理: 多个用户订阅 天气预报,当天气变化,会通知给各个观察者

  • Observable 被观察者 产生事件
  • Observer 观察者 观察事件
  • subscribe 订阅
  • event 事件

3. 基本使用

依赖

implementation "io.reactivex.rxjava2:rxjava:2.1.3" // 必要rxjava2依赖
implementation "io.reactivex.rxjava2:rxandroid:2.0.1" // 必要rxandrroid依赖,切线程时需要用到

代码

// RxJava的链式操作
Observable.create(new ObservableOnSubscribe<Integer>() {
    // 1. 创建被观察者 & 生产事件
    @Override
    public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
        emitter.onNext(1);
        emitter.onNext(2);
        emitter.onNext(3);
        emitter.onComplete();
    }
}).subscribe(new Observer<Integer>() {
// 2. 通过通过订阅(subscribe)连接观察者和被观察者
// 3. 创建观察者 & 定义响应事件的行为
    @Override
    public void onSubscribe(Disposable d) {
    Log.d(TAG, "开始采用subscribe连接");
}
    // 默认最先调用复写的 onSubscribe()
    @Override
    public void onNext(Integer value) {
        Log.d(TAG, "对Next事件"+ value +"作出响应" );
    }
    @Override
    public void onError(Throwable e) {
        Log.d(TAG, "对Error事件作出响应");
    }
    @Override
    public void onComplete() {
        Log.d(TAG, "对Complete事件作出响应");
    }
    });
}
}
注:整体方法调用顺序:观察者.onSubscribe()> 被观察者.subscribe()> 观察者.onNext()>观察者.onComplete()

4.常用操作符

4.1 map

对 被观察者发送的每1个事件都通过 指定的函数 处理,从而变换成另外一种事件,即 将被观察者发送的事件转换为任意的类型事件。

// 采用RxJava基于事件流的链式操作
Observable.create(new ObservableOnSubscribe<Integer>() {
// 1. 被观察者发送事件 = 参数为整型 = 1、2、3
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
    emitter.onNext(1);
    emitter.onNext(2);
    emitter.onNext(3);
}
    // 2. 使用Map变换操作符中的Function函数对被观察者发送的事件进行统一变换:整型变换成字符串类型
}).map(new Function<Integer, String>() {
    @Override
    public String apply(Integer integer) throws Exception {
    return "使用 Map变换操作符 将事件" + integer +"的参数从 整型"+integer + " 变换成 字符串类型" + integer ;
}
}).subscribe(new Consumer<String>() {
    // 3. 观察者接收事件时,是接收到变换后的事件 = 字符串类型
    @Override
    public void accept(String s) throws Exception {
        Log.d(TAG, s);
    }
});

4.2 flatmap

将被观察者发送的事件序列进行 拆分 & 单独转换,再合并成一个新的事件序列,最后再进行发送
原理

// 采用RxJava基于事件流的链式操作
Observable.create(new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
        emitter.onNext(1);
        emitter.onNext(2);
        emitter.onNext(3);
    }
    // 采用flatMap()变换操作符
    }).flatMap(new Function<Integer, ObservableSource<String>>() {
        @Override
        public ObservableSource<String> apply(Integer integer) throws Exception {
            final List<String> list = new ArrayList<>();
            for (int i = 0; i < 3; i++) {
            list.add("我是事件 " + integer + "拆分后的子事件" + i);
             // 通过flatMap中将被观察者生产的事件序列先进行拆分,再将每个事件转换为一个新的发送三个String事件
            // 最终合并,再发送给被观察者
            }
            return Observable.fromIterable(list);
        }
    }).subscribe(new Consumer<String>() {
        @Override
        public void accept(String s) throws Exception {
            Log.d(TAG, s);
        }
    });

注:新合并生成的事件序列顺序是无序的,即 与旧序列发送事件的顺序无关

4.3 concatmap

类似FlatMap()操作符与FlatMap()的 区别在于:拆分 & 重新合并生成的事件序列 的顺序 = 被观察者旧序列生产的顺序

// 采用RxJava基于事件流的链式操作
Observable.create(new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
        emitter.onNext(1);
        emitter.onNext(2);
        emitter.onNext(3);
    }
// 采用concatMap()变换操作符
}).concatMap(new Function<Integer, ObservableSource<String>>() {
    @Override
    public ObservableSource<String> apply(Integer integer) throws Exception {
        final List<String> list = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            list.add("我是事件 " + integer + "拆分后的子事件" + i);
    // 通过concatMap中将被观察者生产的事件序列先进行拆分,再将每个事件转换为一个新的发送三个String事件
    // 最终合并,再发送给被观察者
        }
        return Observable.fromIterable(list);
    }
}).subscribe(new Consumer<String>() {
    @Override
    public void accept(String s) throws Exception {
        Log.d(TAG, s);
    }
});

4.4 interval 实现倒计时功能

	   /** initialDelay 初始延迟时间
         * period 间隔时间
         * TimeUnit 时间单位
         * */
   final Observable<Long> observable = Observable.interval(1, 1, TimeUnit.SECONDS)
                .take(4);// 倒计时 次数限制
        observable.subscribe(new Observer<Long>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(Long aLong) {

                Log.d(TAG, "onNext: " + aLong);

            }

            @Override
            public void onError(Throwable e) {

                Log.d(TAG, "onError: ");
            }

            @Override
            public void onComplete() {

                Log.d(TAG, "onComplete: ");
            }
        });

5.Retrofit 结合Rxjava

5.1 添加依赖

implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0' // 必要依赖,解析json字符所用
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0' // 必要依赖,和Rxjava结合必须用到,下面会提到

implementation "io.reactivex.rxjava2:rxjava:2.1.3" // 必要rxjava2依赖
implementation "io.reactivex.rxjava2:rxandroid:2.0.1" // 必要rxandrroid依赖,切线程时需要用到

5.2 创建bean 和网络请求的接口

注意使用的是Observable对象。

public interface ApiService {
    @GET("10/{page}")
    Observable<Bean> getData2(@Path("page") int page);
}

5.3 创建Retrofit 实例

Retrofit build = new Retrofit.Builder()
    .baseUrl(mBaseUrl)
    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//支持Rxjava
    .addConverterFactory(GsonConverterFactory.create())//设置数据解析器
.build();
ApiService apiService = build.create(ApiService.class);
Observable<Bean> data = apiService.getData2(1);

5.4 处理数据

在子线程订阅该事件
在主线程观察数据的变化
对数据返回的订阅

  data2.subscribeOn(Schedulers.io())// 在IO线程进行网络请求
                .observeOn(AndroidSchedulers.mainThread()) // 回到主线程 处理请求结果
                .subscribe(new Observer<Bean>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                     
                        Log.d(TAG, "onSubscribe: " + Thread.currentThread().getName());
                    }


                    @Override
                    public void onNext(Bean bean) {
                    
                        Log.d(TAG, "onNext: " + Thread.currentThread().getName());
                    }


                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "onError: " + Thread.currentThread().getName());
                    }


                    @Override
                    public void onComplete() {
                        Log.d(TAG, "onComplete: " + Thread.currentThread().getName());
                    }
                });

6.Rxjava 源码 分析图

在这里插入图片描述
create方法,创建一个ObservableCreate,实现了Observable接口。其实是一个被观察者对象,内部onnext oncomplete onerror方法。
同时还传入了一个ObservableOnSubscribe对象,该对象是个回调接口而已。

public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
        ObjectHelper.requireNonNull(source, "source is null");
        return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
    }
public final class ObservableCreate<T> extends Observable<T> {
    final ObservableOnSubscribe<T> source;

    public ObservableCreate(ObservableOnSubscribe<T> source) {
        this.source = source;
    }
	subscribeActual()
	onNext()
	onComplete()
	onError()
}

最终还是返回一个被观察者对象。
重要的是subscribe方法。

 public final void subscribe(Observer<? super T> observer) {
        ObjectHelper.requireNonNull(observer, "observer is null");
        try {
            observer = RxJavaPlugins.onSubscribe(this, observer);
 

            subscribeActual(observer);
        } catch (NullPointerException e) { // NOPMD
            throw e;
        } catch (Throwable e) {
           
        }
    }

subscribeActual是个抽象方法,他的具体实现在ObservableCreate 类里。

  @Override
    protected void subscribeActual(Observer<? super T> observer) {
        CreateEmitter<T> parent = new CreateEmitter<T>(observer);
        observer.onSubscribe(parent); //1

        try {
            source.subscribe(parent);//2
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);
        }
    }

1 是响应处理事件前的处理
2.是接口回调里,要添加具体的事件了。

 Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                emitter.onNext("hello");
                emitter.onComplete();
            }
        })

hello 是一个事件,onComplete也是一个事件。
CreateEmitter是ObservableEmitter的实现类。是一个包装后的发射器对象,会产生事件。CreateEmitter触发onnext onComplete onError 这些方法,会直接调用observer的诸多方法,从而实现观察者模式的效果。

 static final class CreateEmitter<T> extends AtomicReference<Disposable>
    implements ObservableEmitter<T>, Disposable {

        private static final long serialVersionUID = -3434801548987643227L;

        final Observer<? super T> observer;

        CreateEmitter(Observer<? super T> observer) {
            this.observer = observer;
        }

        @Override
        public void onNext(T t) {
            if (t == null) {
               
                return;
            }
            if (!isDisposed()) {
                observer.onNext(t);
            }
        }

        @Override
        public void onError(Throwable t) {
            if (!tryOnError(t)) {
                RxJavaPlugins.onError(t);
            }
        }
}
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值