遇到新的知识我通常从三个方面去快速学习(what - 是什么 why - 为什么用它,它解决了什么样的问题 how - 如何使用),接下来我就从这三个方面来分析.

  • 1.what?
  • RxJava 到底是什么?让我们直接跳过官方那种晦涩的追求精确的定义,其实初学RxJava只要把握两点:
  • 观察者模式 和 异步,就基本可以熟练使用RxJava了。异步 在这里并不需要做太多的解释,因为在概念和使用上,并没有太多高深的东西。大概就是你脑子里想能到的那些多线程,线程切换这些东西。我会在后面会讲解它的用法。说到根上,它就是一个实现异步操作的库.
  • 我们先把 观察者模式 说清楚 “按下开关,台灯灯亮”
    在这个事件中,台灯作为观察者,开关作为被观察者,台灯透过电线来观察开关的状态来并做出相应的处理
  • 开关(被观察者)作为事件的产生方(生产“开”和“关”这两个事件),是主动的,是整个开灯事理流程的起点。
  • 台灯(观察者)作为事件的处理方(处理“灯亮”和“灯灭”这两个事件),是被动的,是整个开灯事件流程的终点。
  • 在起点和终点之间,即事件传递的过程中是可以被加工,过滤,转换,合并等等方式处理的。
  • 2.why?
  • 简洁,并不是指代码量上的那种简洁,而是逻辑上的简洁,随着程序逻辑变得越来越复杂,它依然能够保持简洁。
  • 3.how?
  • RxJava也是基于观察者模式来组建自己的程序逻辑的,就是构建被观察者(Observable),观察者(Observer/Subscriber),然后建立二者的订阅关系(就像那根电线,连接起台灯和开关)实现观察,在事件传递过程中还可以对事件做各种处理。
  • 上用法
  • 简单使用
private void helloWorldSimple() {
        //创建消费者,消费者接受string类型的字符串
        Consumer<String> consumer = new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.d(TAG, "accept " + s);
            }
        };

        //被观察者发出Hello World, 并且指定该事件的消费者为consumer
        //从代码上看是 被观察者订阅了观察者(consumer),为什么是这样的呢?在我们看来应该是consumer订阅了被观察者,,,
        //之所以这样写是为了保证 流式API调用风格(我理解是链式编程,如下)
        //由于被观察者产生事件,是事件的起点,那么开头就是用Observable这个主体调用来创建被观察者,产生事件,为了
        // 保证流式API调用规则,就直接让Observable作为唯一的调用主体,一路调用下去。
        Observable.just("hello world").subscribe(consumer);
    }
  • 升级使用
private void helloWorldComplex() {
        //observer 可以看出完整版的comsumer
        Observer<String> observer = new Observer<String>() {

            //当Observable调用subscribe方法时会回调该方法
            @Override
            public void onSubscribe(Disposable d) {
                Log.d(TAG, "onSubscribe ");
            }

            @Override
            public void onNext(String value) {
                Log.d(TAG, "onNext " + value);
            }

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

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

        Observable.just("hello world").subscribe(observer);
    }
  • 进阶使用
private void helloWorldHard() {
        //创建一个观察者
        Observer<String> observer = new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.d(TAG, "onSubscribe ");
            }

            @Override
            public void onNext(String value) {
                Log.d(TAG, "onNext " + value);
            }

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

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

        //创建一个被观察者
        Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {
                e.onNext("hello world");  //调用观察者的onnext方法
                e.onComplete();
            }
        });

        observable.subscribe(observer);
    }
  • 下面介绍一下RxJava的操作符
  • 变换 map 操作符
private void mapDemo() {
        //将路径字符串转换为图片
        String imagUrl = "http://192.168.18.45:8080/GooglePlayServer/image?name=app/com.renren.mobile.android/screen0.jpg";

        Observable.just(imagUrl)
                .subscribeOn(Schedulers.newThread())   //指定了被观察者执行的线程环境,在子线程中执行网络请求
                .map(new Function<String, Bitmap>() {
                    @Override
                    public Bitmap apply(String s) throws Exception {
                        return createBitmap(s);
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())  //切换到主线程中执行onNext() 更新ui
                .subscribe(new Observer<Bitmap>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Bitmap value) {
                        Log.d(TAG, "onNext ");
                        //显示图片
                        mImage.setImageBitmap(value);
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

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

    /**
     * 通该方法得到bitmap对象
     * 网络请求属于耗时操作,需要在子线程中进行  RxJava再代码中完成线程调度
     *
     * @param s imagurl
     * @return Bitmap
     */
    private Bitmap createBitmap(String s) {
        try {
            URL url = new URL(s);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            if (connection.getResponseCode() == 200) {
                InputStream inputStream = connection.getInputStream();
                Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                return bitmap;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
  • 筛选 filter 操作符
private void filterDemo() {
        //Consumer可以看成精简版的observer
        Consumer<String> consumer = new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.d(TAG, "accept " + s);  //这里观察者接收到包子
            }
        };

        Observable.just("包子", "馒头", "稀饭")
                .filter(new Predicate<String>() {
                    @Override
                    public boolean test(String s) throws Exception {
                        return s.equals("包子");  //只允许包子通过测试
                    }
                })
                .subscribe(consumer);
    }
  • flatmap 能够链式地完成数据类型的转换和加工
private void flatmapDemo() {
        //遍历学校中每个班级的每个同学,按照以前方式
        //        for (int i = 0; i < 3; i++) {
        //            for (int j = 0; j < 3; j++) {
        //                for (int k = 0; k < 3; k++) {
        //                    伪代码
        //                }
        //            }
        //        }

        //这样的代码可读性很差,数据越复杂越难读

        //遍历学校中每个班级的所有组中的所有学生
        //使用这种方式不管有多少层,代码的阅读性不会变得复杂
        Observable.fromIterable(new School().mClasses)
                .flatMap(new Function<Class, ObservableSource<Group>>() {
                    @Override
                    public ObservableSource<Group> apply(Class aClass) throws Exception {
                        Log.d(TAG, "apply " + aClass.toString());
                        return Observable.fromIterable(aClass.group);
                    }
                })
                .flatMap(new Function<Group, ObservableSource<Student>>() {
                    @Override
                    public ObservableSource<Student> apply(Group group) throws Exception {
                        Log.d(TAG, "apply " + group.toString());
                        return Observable.fromIterable(group.mStudents);
                    }
                }).subscribe(new Observer<Student>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(Student value) {
                Log.d(TAG, "onNext " + value.toString());
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        });

    }