Rxjava2预览

一.关键字:ObservableEmitter

.create(observableEmitter->{//就是这个东西

//....    

})

Emitter就是发射器的意思,该发射器可以:onNext(),onComplete()和onError()

注意:
- 上游无限onNext,下游无限接收onNext
- 上游发送onComplect,此时的下游收到onComplect事件后不再继续接收事件
- 上游发送onError,此时下游不再接收事件
- 上游也可以不发送onComplete和onError
- onComplete和onError唯一并且互斥

二.关键字:Dispisable

中文:Disposable–一次性的,可任意处理的,免洗的:

这个相当于上下游管子的一个机关,他可以切断管道

调用dispose()并不会导致上游不再发送事件,上游会继续发送剩余的事件;但是下游不再接收

new Observer<Integer>() {
            private Disposable mDisposable;
            private int i;

            @Override
            public void onSubscribe(Disposable d) {
                Log.d(TAG, "subscribe");
                mDisposable = d;
            }

            @Override
            public void onNext(Integer value) {
                Log.d(TAG, "onNext: " + value);
                i++;
                if (i == 2) {
                    Log.d(TAG, "dispose");
                    mDisposable.dispose();
                    Log.d(TAG, "isDisposed : " + mDisposable.isDisposed());
                }
            }

            @Override
            public void onError(Throwable e) {
                Log.d(TAG, "error");
            }

            @Override
            public void onComplete() {
                Log.d(TAG, "complete");
            }
        }

Disposable可以切断下游的接收,但是上游依然会执行
Disposable的用处不止这些,线程的调度依然会使用他

三.线程的调用:将上游的管子放在子线程里面
observable.subscribeOn(Schedulers.newThread())                                              
            .observeOn(AndroidSchedulers.mainThread())                                          
            .subscribe(consumer);

简单的来说:subscribeOn():指定上游事件的线程
oberveOn():指定下游接收事件的线程

observable.subscribeOn(Schedulers.newThread())     
         .subscribeOn(Schedulers.io())              
         .observeOn(AndroidSchedulers.mainThread()) 
         .observeOn(Schedulers.io())                
         .subscribe(consumer);

subscribeOn:只有第一次指定的有效
observeOn:则是最后一次有效

observable.subscribeOn(Schedulers.newThread())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.d(TAG, "After observeOn(mainThread), current thread is: " + Thread.currentThread().getName());
                    }
                })
                .observeOn(Schedulers.io())
                .doOnNext(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.d(TAG, "After observeOn(io), current thread is : " + Thread.currentThread().getName());
                    }
                })
                .subscribe(consumer);

结果:

D/TAG: Observable thread is : RxNewThreadScheduler-1                                             
D/TAG: emit 1                                                                                    
D/TAG: After observeOn(mainThread), current thread is: main                                      
D/TAG: After observeOn(io), current thread is : RxCachedThreadScheduler-2                        
D/TAG: Observer thread is :RxCachedThreadScheduler-2                                             
D/TAG: onNext: 1

其实就是水管一样切换了,后面就一直是这样了

四.在Rxjava中,内置了线程选项供我们选择:

代码应用
Schedules.io()代表io操作的线程,用于网络,文件读写等io密集
Schedules.computation代表CPU计算密集型
Schedules.newThread()常规新线程
AndroidSchedulers.mainThread()Android的主线程
五.网络请求奔溃和Disposable
Api api = retrofit.create(Api.class);
        api.login(request)
             .subscribeOn(Schedulers.io())               //在IO线程进行网络请求
             .observeOn(AndroidSchedulers.mainThread())  //回到主线程去处理请求结果
            .subscribe(new Observer<LoginResponse>() {
                @Override
                public void onSubscribe(Disposable d) {}

                @Override
                public void onNext(LoginResponse value) {}

                @Override
                public void onError(Throwable e) {
                    Toast.makeText(mContext, "登录失败", Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onComplete() {
                    Toast.makeText(mContext, "登录成功", Toast.LENGTH_SHORT).show();
                }
            });

如上图,我们需要Disposable#dispose()方法切断水管,使得下游收不到事件,因此我们可以在Activity中将这个disposable保存起来,在Activitiy退出时候,切断即可;

假如有多个disposable.rxjava内置了一个容器CompositeDisposable,每当我们得到一个Disposable使用CompositeDisposable#add()将他添加,退出的时候调用CompositeDisposable#clear()切断

六.操作符号:Map

作用:就是对上游发送的每一个事件应用一个函数,使得每个事件都按照指定的函数去变化
image

如图:map就是将圆形事件转换成矩形事件,从而导致下游接收的事件变成矩形

  Observable.create((ObservableOnSubscribe<Integer>) emitter -> {
            emitter.onNext(1);
            emitter.onNext(2);
            emitter.onNext(3);
        }).map(integer -> "This is result " + integer)
                .subscribeOn(Schedulers.io())
                .subscribe(new Observer<String>() {
                    private Disposable mDisposable;
                    private int i;
                    @Override
                    public void onSubscribe(Disposable d) {
                        mDisposable = d;
                    }

                    @Override
                    public void onNext(String integer) {
                    }
                    @Override
                    public void onError(Throwable e) {
                    }
                    @Override
                    public void onComplete() {

                    }
                });

上面就是把圆形事件(Interger)变成矩形事件(String)了

七. 操作符:FlatMap(不保证顺序) concatMap(保证顺序)

作用:将上游Obervable变换成多个发送事件的Observalbes,然后将他们发射的事件合并在一个单独的Obervable里面:
image

上游每发送一个事件,flatMap都将创建一个新的水管,然后发送转换之后的新的事件,下游接收的就是新的水管发送的数据.不过:flatMap并不保证事件的顺序,;如果需要保证顺序的话,需要使用concatMap
如:

   Observable.create((ObservableOnSubscribe<Integer>) emitter -> {
            emitter.onNext(1);
            emitter.onNext(2);
            emitter.onNext(3);
        }).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("I am value " + integer);
                }
                return Observable.fromIterable(list).delay(10, TimeUnit.MICROSECONDS);
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.d("tag", s);
            }
        });

结果:

D/TAG: I am value 1
D/TAG: I am value 1
D/TAG: I am value 1
D/TAG: I am value 3
D/TAG: I am value 3
D/TAG: I am value 3
D/TAG: I am value 2
D/TAG: I am value 2
D/TAG: I am value 2

可以看出没有按照onNext的顺序执行,当我们把flatMap编程concatMap的时候

D/TAG: I am value 1   
D/TAG: I am value 1   
D/TAG: I am value 1   
D/TAG: I am value 2   
D/TAG: I am value 2   
D/TAG: I am value 2   
D/TAG: I am value 3   
D/TAG: I am value 3   
D/TAG: I am value 3

就完成按照onNext 的顺序执行

九.实践:注册–>登录一气呵成是怎么样的?

接口:

public interface Api {
    @GET
    Observable<LoginResponse> login(@Body LoginRequest request);

    @GET
    Observable<RegisterResponse> register(@Body RegisterRequest request);
}

使用:

api.register()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .doONext(result->{

    }).observeOn(Schedulers.io)
    .flatMap(result->{
        return api.login(result)
    })
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(loginResult->{

    },error->{

    })

这里的flatMap可以使用concatMap代替,其实可以理解为多个io操作的顺序执行

十.Flowable

我们知道,当上游一次性发送超过128个事件的时候,会抛MissingBackpressureException,的异常,怎么解决呢?

Flowable.create(new FlowableOnSubscribe<Integer>() {
            @Override
            public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {
                for (int i = 0; i < 1000; i++) {
                    Log.d(TAG, "emit " + i);
                    emitter.onNext(i);
                }
            }
        }, BackpressureStrategy.BUFFER)

使用 BackpressureStrategy.BUFFER就是在内存不oom的情况下,无限的事件大小;

而BackpressureStrategy.DROP 和BackpressureStrategy.LATEST 策略是下游不处理就抛弃,后者是最后一个不抛弃;

Flowable 有特殊的使用

lowable.interval(1, TimeUnit.MICROSECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<Long>() {
}

这样会直接抛MissingBackpressureException异常
这是因为我们每个给定BackPressure的策略
使用:
onBackpressureBuffer()
onBackpressureDrop()
onBackpressureLatest()

就可以了

Flowable.interval(1, TimeUnit.MICROSECONDS)
                .onBackpressureDrop()  //加上背压策略
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<Long>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        Log.d(TAG, "onSubscribe");
                        mSubscription = s;
                        s.request(Long.MAX_VALUE);
                    }

                    @Override
                    public void onNext(Long aLong) {
                        Log.d(TAG, "onNext: " + aLong);
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                    @Override
                    public void onError(Throwable t) {
                        Log.w(TAG, "onError: ", t);
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "onComplete");
                    }
                });
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值