RxJava 使用详情
来源:互联网 发布:淘宝的一件代发是怎么 编辑:程序博客网 时间:2024/06/05 17:16
一概要:
RxJava已经被越来越多的人使用,提及。个人也觉得非常好用,优秀。这里做一个简单的归纳。
1,RxJava是什么:GitHub上介绍(翻译):一个在Java VM上使用可观测的序列来组成异步的,
基于事件的程序的库。简单点:一个实现异步操作的库。类似Handler,与AsyncTask。
2,RxJava优点是什么:相对于Handler/AsyncTask,RxJava使用非常简洁。使用一个链式引用就可以
将整个事件序列串联起来。
3,配置参考github:
https://github.com/ReactiveX/RxJava
https://github.com/ReactiveX/RxAndroid
二原理简析:
#RxJava的异步实现,是通过一个扩展的观察者模式来实现的。
#RxJava有四个基本概念:Observable(被观察者),Observer(观察者),subscribe(订阅),事件。
Observable与Observer通过subscribe来实现订阅关系,从而Observable可以在需要的时候发出事件通知Observer。
#与传统的观察者模式不同,RxJava的回调方法中除了onNext(类似onClick, onEvent),还定义了两个特殊的方法
onError, (事件队列异常),onComplete(事件队列结束语onError互斥)
三使用:
#基本使用
创建Observer(观察者),决定事件触发时的行为。(Subscriber是对Obsever封装了的观察者,比Observer多了
两个方法:onStart(在subscribe刚开始,事件还未被发送之前调用),onunsubscribe(取消订阅)。
Observer<String> observer = new Observer<String>() { @Override public void onCompleted() { LogUtil.i(TAG, "onCompleted"); } @Override public void onError(Throwable throwable) { LogUtil.i(TAG, "onError"); } @Override public void onNext(String s) { LogUtil.i(TAG, "onNext:" + s); } };
创建Observable(被观察者),决定事件什么时候触发,以及触发怎么的事件。
Observable observable = Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { subscriber.onNext("1 times"); subscriber.onNext("2 times"); subscriber.onNext("3 times"); subscriber.onCompleted(); } });#这里OnSubscribe作为create的参数,会被存储在observable对象中,相当于observable的计划表,当Observable
被订阅时,OnSubscribe的call方法就会被调用。然后就会触发订阅者(即观察者的)onNext(三次),onCompleted。
#create是创建事件序列的最基本方法。RxJava还提供其他创建事件序列的快捷方法,from、just...;
from方法:
Observable observable = Observable.from(new String[]{"1 times", "2 times", "3 times"}); //将会依次调用 //onNext("1 times"); //onNext("2 times"); //onNext("3 times"); //onCompleted();just方法:
Observable observable = Observable.just("1 times", "2 times", "3 times"); //将会依次调用 //onNext("1 times"); //onNext("2 times"); //onNext("3 times"); //onCompleted();Subscribe订阅,创建Observable与Observer之后,subscribe方法将两者联系起来。
observable.subscribe(observer); //或 observable.subscribe(subscriber);
subscribe的主要核心代码:
// 注意:这不是 subscribe() 的源码,而是将源码中与性能、兼容性、扩展性有关的代码剔除后的核心代码。 public Subscription subscribe(Subscriber subscriber) { subscriber.onStart(); onSubscribe.call(subscriber); return subscriber; }#重点onSubscribe.call(subscriber)方法,前面分析的create方法,方法中的参数OnSubscribe,作为ObServable的计划表。
除了subscribe(Observer)和subscribe(Subscriber)方法外,还支持不完整定义回调:
Action1<String> nextAction = new Action1<String>() { @Override public void call(String s) { } }; Action1<Throwable> errorAction = new Action1<Throwable>() { @Override public void call(Throwable o) { } }; Action0 completeAction = new Action0() { @Override public void call() { } }; //自动创建Subscriber,使用nextAction,来定义onNext observable.subscribe(nextAction); //自动创建Subscriber,使用nextAction,errorAction来定义onNext与onError observable.subscribe(nextAction, errorAction); //自动创建Subscriber,使用nextAction,errorAction,completeAction来定义onNext,onError,onComplete observable.subscribe(nextAction, errorAction, completeAction);
下面举两个例子:
1,将字符串数组names中的字符串依次打印出来。
//将数组names中的所有字符串打印出来。 String[] names = new String[]{"wangwu", "zhangsan", "lisi"}; Observable.from(names) .subscribe(new Action1<String>() { @Override public void call(String s) { LogUtil.i(TAG, "name:" + s); } });2,由图片id,取得图片并显示:
int resId = R.drawable.aa2; Observable.create(new Observable.OnSubscribe<Drawable>() { @Override public void call(Subscriber<? super Drawable> subscriber) { LogUtil.i(TAG, "currentThread:" + Thread.currentThread()); Drawable drawable = MainActivity.this.getResources().getDrawable(R.drawable.aa2); subscriber.onNext(drawable); subscriber.onCompleted(); } }) .subscribe(new Subscriber<Drawable>() { @Override public void onStart() { super.onStart(); LogUtil.i(TAG, "onStart"); } @Override public void onNext(Drawable drawable) { LogUtil.i(TAG, "currentThread:" + Thread.currentThread()); LogUtil.i(TAG, "onNext"); iv_content.setImageDrawable(drawable); } @Override public void onError(Throwable throwable) { LogUtil.i(TAG, "onError"); } @Override public void onCompleted() { LogUtil.i(TAG, "onCompleted"); } });
高级使用:
1,变换:map、flatMap:将事件序列中的事件或整个事件序列,加工成不同的事件,或事件序列。
场景一,已知学生数组,打印学生的姓名:
Student[] students = ...; Subscriber<String> subscriber = new Subscriber<String>() { @Override public void onNext(String name) { Log.d(tag, name); } ... }; Observable.from(students) .map(new Func1<Student, String>() { @Override public String call(Student student) { return student.getName(); } }) .subscribe(subscriber);场景二,已知学生数组,打印学生的所选课程(课程不唯一):
我们当然可以使用for循环:
Student[] students = ...; Subscriber<Student> subscriber = new Subscriber<Student>() { @Override public void onNext(Student student) { List<Course> courses = student.getCourses(); for (int i = 0; i < courses.size(); i++) { Course course = courses.get(i); Log.d(tag, course.getName()); } } ... }; Observable.from(students) .subscribe(subscriber);或者flatMap:
Student[] students = ...; Subscriber<Course> subscriber = new Subscriber<Course>() { @Override public void onNext(Course course) { Log.d(tag, course.getName()); } ... }; Observable.from(students) .flatMap(new Func1<Student, Observable<Course>>() { @Override public Observable<Course> call(Student student) { return Observable.from(student.getCourses()); } }) .subscribe(subscriber);#flatMap与map不同,call方法返回的是Observable对象。
线程控制要求,利用subscribeOn与observeOn来实现线程控制。subscribeOn实现的是事件发送所在线程,observeOn
事件消耗所在线程(下一个操作),onserveOn可以调用多次,即事件消耗可以多次线程切换。
Scheduler实现异步操作:
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() 指定延伸doOnSubscribe,与subscriber的onStart方法一样在subscribe之后,事件发送前被调用。但是不同点是doOnSubscribe可以
被指定线程。默认情况下doOnSubscribe与subscribe所在的线程相同,如果在doOnSubscribe后又subscribeOn()定义线程,则
依从doOnSubscribe之后的最近的subscribeOn所指定线程:
Observable.create(onSubscribe) .subscribeOn(Schedulers.io()) .doOnSubscribe(new Action0() { @Override public void call() { progressBar.setVisibility(View.VISIBLE); // 需要在主线程执行 } }) .subscribeOn(AndroidSchedulers.mainThread()) // 指定主线程 .observeOn(AndroidSchedulers.mainThread()) .subscribe(subscriber);
四避免内存泄漏:
使用CompositeSubscription,收集每一次Subscription,然后在onDestroy中统一注销。
CompositeSubscription compositeSubscription = new CompositeSubscription();//第一步,初始化CompositeSubscrpiton compositeSubscription.add( //第二步,add Subscription Observable.from(names) .subscribe(new Action1<String>() { @Override public void call(String s) { LogUtil.i(TAG, "name:" + s); } }) ); @Override protected void onDestroy() { super.onDestroy();//在Activity销毁的时候,统一取消订阅,释放资源 if(compositeSubscription.isUnsubscribed()){ compositeSubscription.unsubscribe(); } }
文章参考:http://gank.io/post/560e15be2dca930e00da1083#toc_1
- RxJava 使用详情
- Rxjava操作符使用详情(一)
- RXjava封装实现详情页面
- 关于rxjava与retrofit结合详情
- RxJava----使用
- RxJava使用
- RXjava 使用
- GCC使用详情
- GCC使用详情
- ASIHTTPRequest使用详情
- iOS UIlable使用详情
- MongoDB的使用详情
- Swift基础使用详情
- android dialog使用详情
- FMDB使用详情
- Versions 使用详情
- Log4j使用详情总结
- @transactional 使用详情
- 数据科学—数据科学行业的8个关键角色
- DataColumn 对象
- Html5通过js进行页面内搜索
- mysql 多主多从
- 第三次:从稀疏到深度的视觉特征表示
- RxJava 使用详情
- 前端页面小技能
- PAT(乙级)1018
- C++之操作符重载学习笔记
- 使用事件和消息队列实现分布式事务
- 字符串排列组合
- 一步一步理解Java NIO(下)
- 浅谈Web网站架构演变过程[转载]
- 当自动化安装遇到ncurse界面的解决方法(取消交互的通用方法)