您的位置:首页 > 编程语言 > Java开发

RxJava简单应用 基础篇

2016-03-31 16:46 441 查看
一、RxJava的简单介绍

在GitHub里面,RxJava的官方定义是:"a
libraryforcomposingasynchronousandevent-basedprogramsusingobservablesequencesfortheJavaVM"这里大概翻译是:一个在
JavaVM上使用可观测的序列来组成异步的、基于事件的程序的库。

笔者这里总结本质定义RxJava这个库就是以异步作为基准的应用库。

二、RxJava的优势
无论如何,RxJava最大的在于“简洁、异步!”在Android中,比较常用的异步方式有AsyncTasK或者Handler,但是RxJava相对于其他的异步处理方式中,会显示得更加简洁。我们做过开发也知道,如果在一个异步处理的方法中,如果逻辑比较复杂,相信代码会变得越来越复杂,更加难被读懂。
但是,RxJava最大优势能够依然保持简洁。

这里举个例子:
首先场景:在阅读软件中,需求是需要在遍历内存卡下面存在的文档,并且显示更新在界面中。
1.这是比较常见的实现方法(Thread负责后台逻辑+handler负责更新UI)

finalStringfilePath=Environment.getExternalStorageDirectory().getPath();//获取跟目录
newThread(){
@Override
publicvoidrun(){
super.run();
Filefiles=newFile(filePath);
Filefile[]=files.listFiles();
for(inti=0;i<file.length;i++){
if(file[i].getName().endsWith(".txt")){
paths.add(file[i].getPath());
}
}
handler.sendEmptyMessage(0);//handler更新UI
}
}.start();


2.使用RxJava实现方式

finalStringfilePath=Environment.getExternalStorageDirectory().getPath();//获取跟目录
Filefiles=newFile(filePath);
Filefile[]=files.listFiles();
Observable.from(file)
.map(newFunc1<File,String>(){
@Override
publicStringcall(Filefile){
if(file.getName().endsWith(".txt"))
returnfile.getPath();
return"";
}
})
.subscribeOn(Schedulers.io())//指定subscribe在io线程
.observeOn(AndroidSchedulers.mainThread())//回调是主线程
.subscribe(newAction1<String>(){
@Override
publicvoidcall(Stringpath){
bookView.addFile(path);//自定义书架View,添加文件路径
}
});


如果读者懂得lambda方式的写法,RxJava还可以变化为如下:

Observable.from(file)
.map(path->file.getPath)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(path->bookView.addFile(path));


够清晰吧!





估计在看过这两个对比之后,会说RxJava并没什么卵用==,这里笔者只是举个简单的例子更好说明了RxJava中发布者与订阅者的两者关系。如果读者还想深入,RxJava提供的API文档还是相当多的操作符,功能还是更加强大的,这里给个传送门:文档传送门

说起f发布者(Observable)与订阅中(subscribe)两者之间的关系,相信用过EventBus的读者,对于这个概念是比较熟悉的。

RxJava有四个基本概念:
Observable
(可观察者,即被观察者)、
Observer
(观察者)、
subscribe
(订阅)、事件。
Observable
Observer
通过
subscribe()
方法实现订阅关系,从而
Observable
可以在需要的时候发出事件来通知
Observer


RxJava与传统观察者模式不同,RxJava的事件回调方法除了普通事件
onNext()
(相当于
onClick()
/
onEvent()
)之外,还定义了两个特殊的事件:
onCompleted()
onError()


onCompleted()
:
事件队列完结。RxJava不仅把每个事件单独处理,还会把它们看做一个队列。RxJava规定,当不会再有新的
onNext()
发出时,需要触发
onCompleted()
方法作为标志。
onError()
:
事件队列异常。在事件处理过程中出异常时,
onError()
会被触发,同时队列自动终止,不允许再有事件发出。
在一个正确运行的事件序列中,
onCompleted()
onError()
有且只有一个,并且是事件序列中的最后一个。需要注意的是,
onCompleted()
onError()
二者也是互斥的,即在队列中调用了其中一个,就不应该再调用另一个。

三、RxJava的基础应用

1.最基本的应用(创建观察者与订阅者,并且通过注册实现关联)

//定义一个观察者具体事件发布
Observable<String>mObservable=Observable.create(newObservable.OnSubscribe<String>(){
@Override
publicvoidcall(Subscriber<?superString>subscriber){
subscriber.onNext("Hello,world!wusy");
subscriber.onCompleted();
}
});
//定义一个订阅者具体行为操作
Subscriber<String>mSubscriber=newSubscriber<String>(){
@Override
publicvoidonCompleted(){
}
@Override
publicvoidonError(Throwablee){
}
@Override
publicvoidonNext(Strings){
Log.i(TAG,s.toString());
}
};
//观察者注册订阅者
mObservable.subscribe(mSubscriber);


也可以更简单实例化:

Observable.just("myrxjava").subscribe(newAction1<String>(){
@Override
publicvoidcall(Strings){
Log.i(TAG,s.toString());
}
});


又或者:

Observable.just(“myrxjava”)
.subscribe(s->Log.i(TAG,s.toString()));


2.RxJava中操作符简单应用

对于RxJava的应用中,这个库无非强大的就是异步操作中,各种操作符的运用,这里笔者简单举例部分常见的操作符。

(1)just与from

使用场景:在有时候,我们发布的事件是多件,但是订阅者只需要一个即可,那么我们要写多个Observable吗?答案是:不需要。这里RxJava提供了两个操作符,分别为:just与from。两者实现功能是等价的,都可以同时初始化多个Observable,并且发布到同一个订阅者。具体实现方式如下:

Observable.just("1","2","3").subscribe(newAction1<String>(){
@Override
publicvoidcall(Strings){
Log.i(TAG,s);
}
});
String[]datas={"4","5","6"};//等价于jsut(...)
Observable.from(datas).subscribe(newAction1<String>(){
@Override
publicvoidcall(Strings){
Log.i(TAG,s);
}
});


(2)强大的变换map

使用场景,当我们发布一个事件的时候,例如发布的时候自带了一个网络图片链接,我们不希望在订阅者处理事件的时候,还要跑将url转化为Bitmap的逻辑(因为这样一定程度会消耗在主线程的事件,造成界面卡顿),因此我们希望有个机制可以帮我们将url转化成Bitmap,这就是操作符map的操作功能,具体实现如下:

StringimgUrl="";
Observable.just(imgUrl)
.map(newFunc1<String,Bitmap>(){
@Override
publicBitmapcall(Strings){
Bitmapbitmap=ToolUtils.url2Bitmap(s);
returnbitmap;
}
})
.subscribe(newAction1<Bitmap>(){
@Override
publicvoidcall(Bitmapbitmap){
imagview.
setImageBitmap(bitmap);
}
});


(3)强大的变换flatMap

使用场景:在上面案例中Map只能做一对一的转化。假如有一个场景,在一个学生对象中,拥有属性课程,并且一个学生可以拥有多个课程信息。这里如果用map将学生转化为课程信息,明显这种一对多的场景map实用不了,因此我们也希望有个新的机制可以对一对多场景进行转化,具体实现如下:

List<Student>datas=newArrayList<>();
for(inti=0;i<10;i++){
StringcuoursName=Integer.toString(i)+"同学课程";
String[]cours={cuoursName,cuoursName,cuoursName,cuoursName,cuoursName,cuoursName,cuoursName,cuoursName,cuoursName};
Studentstudent=newStudent(Integer.toString(i)+"同学",cours);
datas.add(student);
}
Subscriber<String>mSubscriber=newSubscriber<String>(){
@Override
publicvoidonCompleted(){}
@Override
publicvoidonError(Throwablee){}
@Override
publicvoidonNext(Strings){
Log.i(TAG,s);
}
};
Observable.from(datas).flatMap(newFunc1<Student,Observable<String>>(){
@Override
publicObservable<String>call(Studentstudent){
Log.i(TAG,student.getName());
returnObservable.from(student.getCours());
}
}).subscribe(mSubscriber);


读者阅读到这里,也许会觉得flatMap比较难理解,笔者第一次接触的时候也相对觉得的确不好理解,如果你按照递归的方式去思考这个操作符,flatMap与map唯一的去吧,就是回调call的时候还是返回了一个发布者Observable,因此在订阅者接收的时候,其实是多次性被触发了。

RxJava在Android应用中,现在并不是常见,但是这种观察者模式是比较典型一种事件分发模式。这里分享个一个开源,用RxJava写的RxEventBus,这里给出传送门,写的不错。

今天整理到这里,希望对读者有帮助

傻小孩b

20160331
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: