RxJava简单应用 基础篇

一、RxJava的简单介绍
在GitHub里面,RxJava的官方定义是:  "a library for composing asynchronous and event-based programs using observable sequences for the Java VM"  这里大概翻译是: 一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库。
笔者这里总结本质定义RxJava这个库就是以异步作为基准的应用库。

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

这里举个例子:
首先场景:在阅读软件中,需求是需要在遍历内存卡下面存在的文档,并且显示更新在界面中。
1.这是比较常见的实现方法(Thread 负责后台逻辑 + handler负责更新UI)
    
    
final String filePath = Environment.getExternalStorageDirectory().getPath();//获取跟目录
new Thread() {
@Override
public void run() {
super.run();
File files = new File(filePath);
File file[] = files.listFiles();
for (int i = 0; i < file.length; i++) {
if (file[i].getName().endsWith(".txt")){
paths.add(file[i].getPath());
}
}
handler . sendEmptyMessage ( 0 ); //handler 更新UI
}
}.start();
2.使用 RxJava实现方式
    
    
final String filePath = Environment.getExternalStorageDirectory().getPath();//获取跟目录
File files = new File(filePath);
File file[] = files.listFiles();
 
Observable.from(file)
.map(new Func1<File, String>() {
@Override
public String call(File file) {
if (file.getName().endsWith(".txt"))
return file.getPath();
return "";
}
})
.subscribeOn(Schedulers.io())//指定subscribe在io线程
.observeOn(AndroidSchedulers.mainThread())//回调是主线程
.subscribe(new Action1<String>() {
@Override
public void call(String path) {
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(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("Hello, world! wusy");
subscriber.onCompleted();
}
});
 
//定义一个订阅者 具体行为操作
Subscriber<String> mSubscriber = new Subscriber<String>() {
@Override
public void onCompleted() {
}
 
@Override
public void onError(Throwable e) {
}
 
@Override
public void onNext(String s) {
Log.i(TAG, s.toString());
}
};
 
//观察者注册订阅者
mObservable.subscribe(mSubscriber);
也可以更简单实例化:
   
   
Observable.just("my rxjava").subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.i(TAG, s.toString());
}
});
又或者:
  
  
Observable.just(“my rxjava”)
.subscribe(s -> Log.i(TAG,s.toString()));
2.RxJava中操作符简单应用
对于 RxJava的应用中,这个库无非强大的就是异步操作中,各种操作符的运用,这里笔者简单举例部分常见的操作符。
(1)just与from
使用场景:在有时候,我们发布的事件是多件,但是订阅者只需要一个即可,那么我们要写多个 Observable 吗?答案是:不需要。这里 RxJava提供了两个操作符,分别为: just与from。两者实现功能是等价的,都可以同时初始化多个 Observable ,并且发布到同一个订阅者。具体实现方式如下:
   
   
Observable.just("1", "2", "3").subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.i(TAG, s);
}
});
 
String[] datas = {"4", "5", "6"};//等价于 jsut(...)
Observable.from(datas).subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.i(TAG, s);
}
});
(2)强大的变换 map
使用场景,当我们发布一个事件的时候,例如发布的时候自带了一个网络图片链接,我们不希望在订阅者处理事件的时候,还要跑将url转化为Bitmap的逻辑(因为这样一定程度会消耗在主线程的事件,造成界面卡顿),因此我们希望有个机制可以帮我们将url转化成Bitmap,这就是操作符map的操作功能,具体实现如下:
   
   
String imgUrl = "";
Observable.just(imgUrl)
.map(new Func1<String, Bitmap>() {
@Override
public Bitmap call(String s) {
Bitmap bitmap = ToolUtils.url2Bitmap(s);
return bitmap ;
}
})
.subscribe(new Action1<Bitmap>() {
@Override
public void call(Bitmap bitmap) {
imagview. setImageBitmap(bitmap);
}
});
(3)强大的变换flatMap
使用场景:在上面案例中Map只能做一对一的转化。假如有一个场景,在一个学生对象中,拥有属性课程,并且一个学生可以拥有多个课程信息。这里如果用map将学生转化为课程信息,明显这种一对多的场景map实用不了,因此我们也希望有个新的机制可以对一对多场景进行转化,具体实现如下:
   
   
List<Student> datas = new ArrayList<>();
for (int i = 0; i < 10; i++) {
String cuoursName = Integer.toString(i) + "同学课程";
String[] cours = {cuoursName, cuoursName, cuoursName, cuoursName, cuoursName, cuoursName, cuoursName, cuoursName, cuoursName};
Student student = new Student(Integer.toString(i) + "同学", cours);
datas.add(student);
}
Subscriber<String> mSubscriber = new Subscriber<String>() {
@Override
public void onCompleted() {}
@Override
public void onError(Throwable e) {}
@Override
public void onNext(String s) {
Log.i(TAG, s);
}
};
 
Observable.from(datas).flatMap(new Func1<Student, Observable<String>>() {
@Override
public Observable<String> call(Student student) {
Log.i(TAG, student.getName());
return Observable.from(student.getCours());
}
}).subscribe(mSubscriber);
读者阅读到这里,也许会觉得 flatMap比较难理解,笔者第一次接触的时候也相对觉得的确不好理解,如果你按照递归的方式去思考这个操作符, flatMap与map唯一的去吧,就是回调call的时候还是返回了一个发布者 Observable ,因此在订阅者接收的时候,其实是多次性被触发了。

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

今天整理到这里,希望对读者有帮助
傻小孩b
20160331


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值