RxJava1.x学习

前言:

    作为一个小菜鸟,以前都没有用过RxJava,但这都丝毫不影响我在这里BB。以前写个异步就是new Thread()+new Handler();或者是使用new AsyncTask();来实现一个异步操作。大清早起来,就准备研究这个RxJava,想看看这个是个什么玩意;

    首先呢,学习一门新东西要先了解他,于是乎我就拿出我的看家本领“百度一下”;百度了一些文章,看着特别棒,讲解的也很详细,可是我TM就是不懂啊!


    抱着“我的智商是没有问题的”这一想法,我又细心的看了两三遍,捋了捋思路,亲自动手敲了下代码,然后发现:


    大佬们写的东西总是站在大佬的角度出发的:哪怕是大佬已经想到了新手可能要比自己略逊一点,但大佬并没有想到新手原来如此的笨(比如我),于是我在学的过程中就想写一些小菜鸟们的入门宝典(从入门到放弃爱不释手);

    不多BB了,下面整点干货!


引入依赖:

    不把库引进来怎么用!

    ·AndroidStudio的小伙伴们可以:

RxJava:
    compile 'io.reactivex:rxjava:1.0.14'
    compile 'io.reactivex:rxandroid:1.0.1'
RxBinding:
  compile 'com.jakewharton.rxbinding:rxbinding:0.4.0'//这个是另一个库,先在这里放着,初学不用理这个,引上边两个就可以了!
    ·Eclipse的小伙伴们可以:

换AndroidStudio吧!

链接: https://pan.baidu.com/s/14jRRvsTRZQjtc8KlZw0rZg 密码: tyyh

买一赠一,顺便还换个开发工具!

    多说一句,因为我学的时候去GitHub看了一下,版本已经更新到了2.0,当时引入的是2.0的依赖,发现问题大了,好多方法都不一样了,多了一些东西,看得我蒙蒙的;


我又重新引的1.x版本,初学者嘛,学会了1之后在延伸到2就容易很多了;除了RxJava之外,上面提到的RxBinding也是这样,本身更新到了2.0版本,也是有一些方法发生了改变。我这里引入的是一个0.4的版本;

库引进来了,到了最关键的怎么用了!你以为我会直接上代码?NoNoNo!先简单介绍几个有趣的概念,后面都会用的到的!

重要概念:

    ·响应式编程

    RxJava 是一个响应式编程框架,采用观察者设计模式。至于什么事观察者设计模式,可以自行百度;

    ·Subscriber

    观察者,接受者,可接收ObservableSubject发射的数据,异步中就是再这里接收数据并处理,一般最终会设置运行在ui线程;

    ·Observable

    被观察者,发射源,数据处理和数据发送是在这里进行的,这里涵盖了好多东西,包含线程,类型转换,网络请求等;

    ·FuncX

    RxJava中封装的一个类,X代表的是参数个数;这个类用来指定有返回值的对象类型回调;

    ·ActionX

    作用和Func相同,只是这个类没有返回值;

    ·操作符

    操作符有很多,指的是在进行响应式编程的过程中用到的一些工具方法,用来满足各类需求;后面会介绍一些重要的操作符,其他的会附上一个连接自行研究;

    ·Scheduler

    线程控制。我们在使用RxJava时无可避免的就是为了解决异步的问题,这个类为我们提供了线程控制,如何在RxJava中自由的切换线程,就要看这个类的了;

看到这里是不是脑海里多了几个关键字?这几个关键字在以后对RxJava的操作中是非常关键的;

代码部分:

    理解了概念了,就得上点硬货了,不然光说不练可是假把式!

举个例子

先从同步开始说起,就是我使用发送者发送一些数据,然后使用接受者收到之后在页面显示一下!就是这么简单!

    页面就不用贴出来了,文字描述一下就好了(一个Button,一个TextView)

    在按钮的监听事件中,点击按钮发送数据

List<String> list = new ArrayList<>();
list.add("Hello!");
list.add("My name is HuJun!");
list.add("And you?");
list.add("How are you?");
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        //第一种方法:使用create()创建一个Observable对象,并且执行相应的操作,发送一些数据到观察者中;
        Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("hello1");
                subscriber.onNext("hello2");
                subscriber.onNext("hello3");
                subscriber.onNext("hello4");
                subscriber.onNext("hello5");
                subscriber.onCompleted();
            }
        }).subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                Log.d("TAG", "call: ");
                tv.append("\n"+s);
            }
        });

        //第二种方法:from方法用于解析一个list,内置创建了一个被观察者对象,并且把list中的每一个item
        //发送到了观察者中,并且自动调用了onCompleted方法;
        Observable.from(list)
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.d("TAG", "call: ");
                        tv.append("\n"+s);
                    }
                });

    }
});
链接:Observable的创建
对于被观察者的创建,根据应用的场景不同,RxJava给我们提供了许多方法,这里就不一一赘述了,放个连接,可以了解一下,这部分也是我转载的。
原文很长,被我拆分了一下,拆成了几个短一点的文章;

上述呢,就是RxJava最简单的一个使用方式;你以为这就结束了吗?学完这个你会发现:然卵用???


我写RxJava的最开始的意图是为了更好的实现异步操作,这个样子那里有半点异步的样子了;

那我就来举个异步的栗子算了;

举例子之前,先说一下RxJava中关于异步的实现;

线程调度器--Scheduler中控制线程依赖一个Scheduler 对象,Scheduler 对象分为一下几类:

Schedulers.immediate()直接在当前线程中运行,相当于不指定线程,这也是RxJava默认的线程方式;
Schedulers.newThread()启用新线程,并且在新线程中执行操作;
Schedulers.io()I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler;区别在于 io() 的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下 io() 比 newThread() 更有效率。
Schedulers.computation()计算所操作的线程,这个计算指的是CPU密集型计算;
AndroidSchedulers.mainThread()Android独有的线程,就是所说的Android的主线程,UI线程;

放下手中的刀,我这就举个异步的例子:


    代入一下场景:

        小明要叫着小李出去打球,可是小李在洗澡,然后小明给小李发消息“我们一会去打球,看到了给我回个消息!”,然后小明就去看电视了,小李洗完澡之后看到消息之后,回消息给小明“完全ojbk!,我们这就走!”,小明收到回复后关掉电视,一起去打球了;

        分析一下的话,这个流程分为:小明发出消息->等待小李看到->小李看到之后回复->小明接收做操作;

        在这个流程中,小明发出消息之后并没有一直等着小李回复,也就是并没有阻塞主线程,而是接着就去看电视了从小明的角度来讲,等待小李回消息就是在子线程中运行的,看电视则是运行在主线程;

        这个问题用RxJava怎么解决呢?

final String xiaoming = "李哥去不去打篮球,看到回复我一下,我先去看电视!";
Observable.create(new Observable.OnSubscribe<String>() {
    @Override
    public void call(Subscriber<? super String> subscriber) {
        subscriber.onNext(xiaoming);
        doWatchTV();//执行看电视操作
        subscriber.onCompleted();
    }
})
        .subscribeOn(Schedulers.newThread())
        .map(new Func1<String, String>() {
            @Override
            public String call(String s) {
                SystemClock.sleep(2000);//过了2000毫秒,小李收到消息
                return s;
            }
        })
        .observeOn(AndroidSchedulers.mainThread())//切换线程
        .subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                //tv.setText("完全ojbk");
                closeTV();//小明收到消息,关闭TV
            }

        });

这看上去确实是一个毫无意义的功能,但是我们可以把他替换为有意义的功能!比如网络加载图片等等;

线程之间的转换:

observeOn() 指定的是 Subscriber 的线程,而这个 Subscriber 并不是(严格说应该为『不一定是』,但这里不妨理解为『不是』)subscribe() 参数中的 Subscriber ,而是 observeOn() 执行时的当前 Observable 所对应的 Subscriber ,即它的直接下级 Subscriber 。换句话说,observeOn() 指定的是它之后的操作所在的线程。因此如果有多次切换线程的需求,只要在每个想要切换线程的位置调用一次 observeOn() 即可。上代码:

Observable.just(1, 2, 3, 4) // IO 线程,由 subscribeOn() 指定
    .subscribeOn(Schedulers.io())
    .observeOn(Schedulers.newThread())
    .map(mapOperator) // 新线程,由 observeOn() 指定
    .observeOn(Schedulers.io())
    .map(mapOperator2) // IO 线程,由 observeOn() 指定
    .observeOn(AndroidSchedulers.mainThread) 
    .subscribe(subscriber);  // Android 主线程,由 observeOn() 指定
这里面还用到了一些工具方法,比如.map()方法,这个方法是用来转换数据时使用的,诸如此类的工具方法有很多,我这里转载了一篇比较详细的,连接贴在这里,可以去参考学习一下;    这段话我一开始也没有理解,后来多看了几遍了解了,白话一点的讲米就是.subscribeOn()方法指定的是创建操作执行时所在的线程,这个方法只有效这一次(可以这样理解),如果执行了这个方法之后,后面没有执行其他的线程切换的方法,那么之后的所有方法运行就都是存在与这个线程中的,如果之后通过.observeOn()方法修改了指定线程,那么这个方法之后则都是运行在这个线程上的;

链接:RxJava操作符大全

看完这些呢,基本上剩下的关于RxJava的部分就要靠自己摸索了,有兴趣也可以翻一翻源码,看看是怎么实现的,可能一开始看不懂,看多了就懂了;

文章结尾,再提一个东西,就是开头也说道过的RxBinding;

都做过监听的设置,看上边的代码不难发现setOnclickLinster的方法写起来好像不是很美观;

于是乎有了这么一个框架,有了它之后,会让你整个的代码看上去就是很舒服的响应式的编码布局,看着就很爽;

使用方法也很简单,我这里举个和RxJava一起用的栗子,更多例子老规矩也是赋个连接,自己去看;


RxBinding:

    不多BB直接上代码:
RxView.clicks(findViewById(R.id.btn_iv))
        .throttleFirst( 2 , TimeUnit.SECONDS )//设置两秒内点击无效
        .subscribe(new Action1<Void>() {
            @Override
            public void call(Void aVoid) {
                Observable.just(urlstr)
                        .map(new Func1<String, Object>() {
                            @Override
                            public Object call(String s) {
                                SystemClock.sleep(2000);
                                return null;
                            }
                        })
                        .subscribeOn(Schedulers.newThread())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Action1<Object>() {
                            @Override
                            public void call(Object object) {
                                tv.setText("完全ojbk!");
                                Log.d(TAG, "call: object-------ok");
                            }
                        });
            }
        });
    这个栗子是响应了一个单击事件,然后线程睡眠两秒后通知ui线程更新数据;

具体的多种用法我就把连接放到这里了,可以去看看

链接:RxBinding使用

好了,到这里就先这样吧,我要去吃饭了,研究这东西研究了一下午了!


关于作者:

    Name:贾恒飞

    等级:菜鸡

    欢迎大佬们支援

    QQ:2757525207

    WX:jy271613

    萌新来骚扰也是可以的;;;;妹子优先哦


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章