RxJava2.0 基本使用,和场景

RxJava接触挺久了,但是在实际项目中大部分都是配合retrofit使网络请求使用,其他需求比较少,就是想用的时候会忘记怎么使用,所以这里做个笔记,希望也能帮到他人

本文基于RxJava2.0

RxJava

自己觉得知道下面几点就比较清楚了

  1. RxJava的异步实现,是通过一种扩展的观察者模式来实现的
  2. RxJava 的观察者模式:Observable (可观察者,即被观察者)、 Observer (观察者)、 subscribe (订阅)、事件。
  3. Observable 和 Observer 通过 subscribe() 方法实现订阅关系,从而 Observable可以在需要的时候发出事件来通知 Observer
那么既然是观察者模式,那我们看下怎么使用

创建被观察者:使用基本的创建方式create()

Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {
                //通知观察者
                e.onNext("通知观察者");
                e.onComplete();
            }
        });

创建观察者

Observer observer = new Observer<String>() {
           //RxJava 2.0 中新增的,传递参数为Disposable ,Disposable 相当于RxJava1.x中的Subscription,用于解除订阅。
            @Override
            public void onSubscribe(Disposable d) {
                //可用于取消订阅
                d.dispose();
                //还可以判断是否处于取消状态
                //boolean b=d.isDisposed();
            }

            //观察者接收到通知,进行相关操作
            @Override
            public void onNext(String o) {
                Log.d("","接收到观察者发出的数据");
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        };

订阅,将被观察者和观察者关联上

observable.subscribe(observer);
其他创建被观察者的方式

just(T…): 将传入的参数依次发送出去

Observable observable = Observable.just("Hello", "Hi", "Aloha");
// 将会依次调用:
// onNext("Hello");
// onNext("Hi");
// onNext("Aloha");
// onCompleted();

Observable.from… 拆分成具体对象后,依次发送出去

String[] words = {"Hello", "Hi", "Aloha"};
Observable observable = Observable.from(words);
// 将会依次调用:
// onNext("Hello");
// onNext("Hi");
// onNext("Aloha");
// onCompleted();
线程的切换–线程控制器的使用(Schedulers)

看下面的code 想大家看下注释就会明白了

 Observable.just("a", "b", "c", "d")
                .subscribeOn(Schedulers.io())//指定数据发射在哪个线程执行
                .observeOn(Schedulers.newThread())//observeOn方法决定他下面的方法执行在哪个线程中
                .map(func1)//一个新线程中执行
                .observeOn(Schedulers.io())//observeOn方法决定他下面的方法执行在哪个线程中
                .map(func2)//io线程执行
                .observeOn(AndroidSchedulers.mainThread())observeOn方法决定他下面的方法执行在哪个线程中
                .subscribe(consumer);//ui线程执行
Function<String, String> func1 = new Function<String, String>() {
        @Override
        public String apply(String s) throws Exception {
            return s + "===newThread===";
        }
    };

    Function<String, String> func2 = new Function<String, String>() {
        @Override
        public String apply(String s) throws Exception {
            return s + "===io===";
        }
    };

    Consumer<String> consumer = new Consumer<String>() {
        @Override
        public void accept(String o) throws Exception {
            Log.d("call", o.toString());
        }
    };
下面我们根据场景来进行使用
  • 场景一: 单请求异步处理(网络请求)
  • 场景二: 多异步请求连续调用
  • 场景三: 进行数组、list的遍历(耗时数据处理)
  • 场景四: 多异步请求合并处理
  • 场景五: 定时操作

    示例中会伴有Rxjava 的操作符出现,使用时会进行说明

场景一: 单请求异步处理(网络请求)

由于在Android UI线程中不能做一些耗时操作,比如网络请求,大文件保存等,所以在开发中经常会碰到异步处理的情况,我们最典型的使用场景是RxJava+Retrofit处理网络请求

@GET("/user")
public Observable<User> getUser(@Query("userId") String userId);
getUser(userId)
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Observer<User>() {
        @Override
        public void onNext(User user) {
            userView.setUser(user);//使用得到的结果数据
        }

        @Override
        public void onCompleted() {
        }

        @Override
        public void onError(Throwable error) {
            // Error handling
            ...
        }
    });
场景er: 多异步请求连续调用

假如在得到User数据后,需要跟新本地的用户数据,也是将新的额数据显示到View上,两步操作都是同时的,这个时候我们可以借助”doOnNext “操作符

“doOnNext “操作符

doOnNext() 方法 是当onNext发生时才会被调用
doOnNext()允许我们在每次输出一个元素之前做一些额外的事情
注意:
在doOnNext()中不要去改变数据的值

processUser(user); // 尝试修正 User 数据
userView.setUser(user);//显示数据

代码

getUser(userId)
    .doOnNext(new Consumer<User>() {
                    @Override
                    public void accept(User user) throws Exception {
                        processUser(user);//更改数据
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())//ui线程
                .subscribe(new Observer<User>() {
                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }

                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(User user) {
                        userView.setUser(user);//展示数据
                    }
                });

如果请求getUser()之前需要getToken接口返回的数据才能访问

使用”flatmap”操作符
作用:将一个类型依据程序逻辑转换成另一种类型

@GET("/token")
public Observable<String> getToken();

@GET("/user")
public Observable<User> getUser(@Query("token") String token, @Query("userId") String userId);
getToken()
    .flatMap(new Function<String, Observable<User>>() {
                    @Override
                    public Observable<User>> apply(String token) throws Exception {
                        return getUser(token, userId);//第二次网络请求
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<User>() {


                    @Override
                    public void onSubscribe(Disposable disposable) {

                    }

                    @Override
                    public void onNext(User user) {
                        //获取到的用户数据
                    }

                    @Override
                    public void onError(Throwable throwable) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
场景三: 进行数组、list的遍历(耗时数据处理)

使用”fromIterable”操作符 ,作用:遍历发送列表的每个Item

ArrayList<String> arr1 = new ArrayList<>();
        arr1.add("url1");
        arr1.add("url2");
        arr1.add("url3");

        Observable.just(arr1)
                .subscribeOn(Schedulers.newThread())//指定数据发射在哪个线程执行
                .flatMap(new Function<List<String>, Observable<String>>() {
                    @Override
                    public Observable<String> apply(List<String> strings) throws Exception {
                        Log.d("flatMap Thread ::: ", Thread.currentThread().getName());
                        return Observable.fromIterable(strings);//遍历列表发送
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())//切换到主线程
                .subscribe(new Consumer<String>() {
                    @Override
                    public void accept(String s) throws Exception {
                        Log.d("subscribe Thread ::: ", Thread.currentThread().getName());
                        Log.d("subscribe === ", s);
                    }
                });
场景四: 多异步请求合并处理

有时需要请求多个接口和,将多个接口请求回来的数据合并后使用,可以使用”zip”操作符
作用:组合多个Observable发射的数据集合,然后再发射这个组合结果Observable

 Observable.zip(getData1(), getData2(), new BiFunction<List<String>, List<String>, String>() {
            @Override
            public String apply(List<String> strings, List<String> strings2) throws Exception {

                return strings.get(0) + strings.get(0);//发送组合后的新数据
            }
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<String>() {
                    @Override
                    public void accept(String s) throws Exception {
                        Log.d("接受新数据:::", s);
                    }
                });
 /**
     * 模拟请求数据1
     *
     * @return
     */
    private Observable<List<String>> getData1() {
        return Observable.create(new ObservableOnSubscribe<List<String>>() {
            @Override
            public void subscribe(ObservableEmitter<List<String>> e) throws Exception {
                ArrayList<String> contacters = new ArrayList<>();
                contacters.add("location:张三");
                contacters.add("location:李四");
                contacters.add("location:王五");
                e.onNext(contacters);
                e.onComplete();
            }
        });
    }

    /**
     * 模拟获取数据2
     *
     * @return
     */
    private Observable<List<String>> getData2() {
        return Observable.create(new ObservableOnSubscribe<List<String>>() {
            @Override
            public void subscribe(ObservableEmitter<List<String>> e) throws Exception {
                ArrayList<String> contacters = new ArrayList<>();
                contacters.add("net:Zeus");
                contacters.add("net:Athena");
                contacters.add("net:Prometheus");
                e.onNext(contacters);
                e.onComplete();
            }
        });
    }
场景五: 定时操作

使用timer做定时操作。当有“x秒后执行y操作”类似的需求的时候,想到使用timer
* 例如:2秒后输出日志“hello world”,然后结束。

 //2秒后执行
        Observable.timer(2, TimeUnit.SECONDS)
                .observeOn(AndroidSchedulers.mainThread())//切换到主线程
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        tv_msg.setText("hello --- world");
                    }
                });

更多操作符使用,后续有时间再记录

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值