Rxjava上手
使用Rxjava框架,我个人觉得最大的好处就是能够很方便的在各个线程当中进行切换,而且代码还能保持很优雅。
在代码里面加上以下内容,便可以使用了。
compile 'io.reactivex:rxjava:1.0.14' compile 'io.reactivex:rxandroid:1.0.1'
只需要掌握以下三部分内容,便可以很方便的使用Rxjava框架了。
1.发射器和接收器
首先来看一下最常规的写法:
//接收器 Observer<String> observer = new Observer<String>() { @Override public void onCompleted() { Log.i("Rx","调用了onCompleted"); } @Override public void onError(Throwable e) { Log.i("Rx","调用了onError"); } @Override public void onNext(String s) { Log.i("Rx","调用了onNext ,"+s); } }; //发射器 Observable observable = Observable.create(new Observable.OnSubscribe<String>(){ @Override public void call(Subscriber<? super String> subscriber) { subscriber.onNext("hello");//发射 subscriber.onNext("hi"); subscriber.onNext("Aloha"); subscriber.onCompleted(); } }); observable.subscribe(observer);//关联发射器和接收器
执行这段代码可以得到如下结果:
在这段代码中,发射器分别发送了“hello”、“hi”、“Aloha”给接收器,
接收器的onNext函数接收到了数据,并打印出来。
在上一段代码当中,接收器当中有onError、onComplete函数,
如果你并不关心这些,那么可以使用Action接口,具体如下:
//发射器 Observable observable = Observable.create(new Observable.OnSubscribe<String>(){ @Override public void call(Subscriber<? super String> subscriber) { subscriber.onNext("hello"); subscriber.onNext("world!"); } }); observable.subscribe(new Action1<String>() {//接收器 @Override public void call(String str) { Log.i("Rx","调用了call ,"+str); } });
代码执行结果如下:
除了采用create函数创建发射器外,还有其他的方式,以下为几种常见的创建方式:
a.使用just( ),将为你创建一个Observable并自动为你调用onNext( )发射数据:
justObservable = Observable.just("just1","just2");//依次发送"just1"和"just2"
b.使用from( ),遍历集合,发送每个item:
List<String> list = new ArrayList<>(); list.add("from1"); list.add("from2"); list.add("from3"); fromObservable = Observable.from(list); //遍历list 每次发送一个 /** 注意,just()方法也可以传list,但是发送的是整个list对象,而from()发送的是list的一个item** /
还有一些其他的创建方式,具体可以参见这篇博客
http://www.jianshu.com/p/5e93c9101dc5
2.操作符
Rxjava框架当中有很多操作符,以下介绍两个最常用的操作符。
Map:能将一个对象转换成为另外一个对象。
如下所示,将路径字符串转变成为图片
Observable.just("path").map(new Func1<String, Bitmap>() {//发射器发送path,map将path变成bitmap @Override public Bitmap call(String s) { Bitmap bitmap = BitmapFactory.decodeFile(s); return bitmap; } }).subscribe(new Action1<Bitmap>() {//接收器接收bitmap @Override public void call(Bitmap bitmap) { image.setImageBitmap(bitmap); } });
flatMap:能将一个发射器转变成为另外一个发射器
举例说明,一个班级包含有多个学生
public class ClassRoom { public String name; public List<Student> stuList; public ClassRoom(){ stuList = new ArrayList<>(); } }
以下代码将一个ClassRoom的发射器转变成为多个Student发射器
Observable.from(list).flatMap(new Func1<ClassRoom, Observable<Student>>() {//将ClassRoom发射器转变成为Student发射器 @Override public Observable<Student> call(ClassRoom classRoom) { return Observable.from(classRoom.stuList); } }) .subscribe(new Action1<Student>() {//接收器接收Student @Override public void call(Student student) { Log.i("Rx","调用了call "+student.name); } });
3.调度
个人认为调度是Rxjava里面最好用的一个功能,能够让代码变得很优雅,具体功能如下:
调度器类型 |
用途 |
Schedulers.computation( ) |
用于计算任务,如事件循环或和回调处理,不要用于IO操作(IO操作请使用Schedulers.io());默认线程数等于处理器的数量 |
Schedulers.from(executor) |
使用指定的Executor作为调度器 |
Schedulers.immediate( ) |
在当前线程立即开始执行任务 |
Schedulers.io( ) |
用于IO密集型任务,如异步阻塞IO操作,这个调度器的线程池会根据需要增长;对于普通的计算任务,请使用Schedulers.computation();Schedulers.io( )默认是一个CachedThreadScheduler,很像一个有线程缓存的新线程调度器 |
Schedulers.newThread( ) |
为每个任务创建一个新线程 |
Schedulers.trampoline( ) |
当其它排队的任务完成后,在当前线程排队开始执行 |
AndroidSchedulers.mainThread() |
此调度器为RxAndroid特有,顾名思义,运行在Android UI线程上 |
举例:
从文件路径当中读取图片然后显示。
由于读取文件比较耗时,所以要新建线程来读取,
读取完之后,必须在UI线程当中显示,所以通常的代码如下
new Thread(new Runnable() { @Override public void run() { final Bitmap bitmap = BitmapFactory.decodeFile("path");//新建线程,从路径当中读取图片; activity.runOnUiThread(new Runnable() { @Override public void run() { image.setImageBitmap(bitmap);//UI线程,将读取的图片显示 } }); } }).start();
如果逻辑稍微复杂一点,代码就会异常臃肿,而使用Rxjava会使代码很优雅
Observable.just("path").map(new Func1<String, Bitmap>() {//发射器 @Override public Bitmap call(String s) { Bitmap bitmap = BitmapFactory.decodeFile(s); return bitmap; } }).subscribeOn(Schedulers.io())//指定发射器在IO线程 .observeOn(AndroidSchedulers.mainThread())//指定接收器在UI线程 .subscribe(new Action1<Bitmap>() {//接收器 @Override public void call(Bitmap bitmap) { image.setImageBitmap(bitmap); } });
只需要使用subscribeOn指定发射器线程,observeOn指定接收器线程,这样便可以方便的在各个线程之间进行切换了。