前言:
作为一个小菜鸟,以前都没有用过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
'//这个是另一个库,先在这里放着,初学不用理这个,引上边两个就可以了!
|
换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
观察者,接受者,可接收Observable 、Subject 发射的数据,异步中就是再这里接收数据并处理,一般最终会设置运行在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() 指定 |
链接: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
萌新来骚扰也是可以的;;;;妹子优先哦