RxJava简介:
可以使代码变的简洁,增加代码的可读性可维护性。
Observable.from(folders)
.flatMap((Func1) (folder) -> { Observable.from(file.listFiles()) })
.filter((Func1) (file) -> { file.getName().endsWith(".png") })
.map((Func1) (file) -> { getBitmapFromFile(file) })
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe((Action1) (bitmap) -> { imageCollectorView.addImage(bitmap) });
使用的是观察者模式,又叫订阅发布模式实现的。
传统的观察者模式:
观察者模式和订阅发布模式是一样的,观察者又叫订阅者,被观察者又叫发布者。
了解与传统的观察者模式区别,避免入坑:
1.在RxJava中这两种名字经常混用,所有要弄清楚谁是观察者(Observer)被观察者(Observable)订阅者(Subscriver)发布者(publisher 暂时没有见到),这也是RxJava容易对初学者造成的困惑。
2.RxJava中在subscrib()之后根据操作符来完成回调方法中的不同方式的响应,传统观察者是在订阅后处于等待的状态,待被观察者发布消息后再进行回调。
使用需要加入下面依赖包
compile'io.reactivex:rxjava:1.2.4'
compile'io.reactivex:rxandroid:1.2.1'
一、使用方法
1.创建被观察者:Observable
2.创建观察者(订阅者):Observer (Subscriber)Observer与Subscriber是继承关系,实现细节不一样
3.订阅 subscribe()
4.订阅之前可以添加操作符,链式的结构
二、几个例子
第一个例子:使用步骤
//步骤1:创建被观察者 除了使用from可以有其他多种方式
Observable observable1=Observable.from(new String[]{"hello","hi","jcc"});
//步骤2:创建观察者 也可以使用Observer Action1 Action2等
Subscriber<String> subscribe=new Subscriber<String>() {
@Override
public void onStart() {
super.onStart();
Log.i("jcc","method1 onStart");
}
@Override
public void onCompleted() {
Log.i("jcc","method1 onCompleted");
}
@Override
public void onError(Throwable e) {
Log.i("jcc","method1 onError"+e.getMessage());
}
@Override
public void onNext(String s) {
Log.i("jcc","method1 onNext "+s);
}
};
//步骤3:订阅
observable1.subscribe(subscribe);
这是一个最简单的使用例子,实现一次打印String数组中字符串。subscribe之后根据需要回调其中的回到方法,很容易根据名字来判断回到顺序,onStart(),onNext(),onComplete()为正常顺序,onError()为异常时调用。
以上是默认的回调顺序,Observable提供create操作符来创建新的Observable自定义回调。也可以使用RxJava库提供的一些类Action1等。
这里只是最简单的实现,后面的编程都是根据 obServable1.subscribe(subscribe)的扩展,或者说所有的RxJava响应式编程的结构都是Obserable.subscribe(Subscriber)这么一个链的扩展。
Obserable .创建操作符(参数) //创建操作符有just、create、from等
.操作符1(参数)
.操作符2(参数)
...
.操作符n(参数)
.subscribe(subscriber);
参数可以是一个匿名内部类。
操作符的属相非常多,数量多说明可以实现的功能也就非常的庞大,我这里写的几个只能算入门级的。
第二个例子:线程的切换(subscribeOn observeOn操作符的使用 )
Observable.create(new Observable.OnSubscribe<Drawable>() {
@Override
public void call(Subscriber<? super Drawable> subscriber) {
Log.i("jcc",Thread.currentThread().getName());
//运行在subscribeOn()操作符设置的线程
Drawable drawable=getTheme().getDrawable(drawalbe);
subscriber.onNext(drawable);
subscriber.onCompleted();
}
})
.subscribeOn(Schedulers.io())//被观察者的回调运行的线程
.observeOn(AndroidSchedulers.mainThread())//观察者的回调运行的线程
.subscribe(new Observer<Drawable>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Drawable drawable) {
//运行在sbuscribeOn设置的线程
((ImageView)findViewById(R.id.iv)).setImageDrawable(drawable);
}
});
这里使用的是一个例子实现的是类似于Handler或者AsyncTask的异步过程,在工作线程中加载资源文件(当然也可以换做网络请求),在主线程中set图片。
第三个例子:Retrofit结合RxJava做网络请求框架
Retrofit是对Okhttp的封装,将请求返回的io流转化为Retrofit的Servcie接口,再通过Gson解析到实体类。
Retrofit中本身不使用RxJava,retrofit的addCallAdatperFactorty()中传入RxJavaCallAdapterFactory.Create()后,异步调用接口可以转化为RxJava的模式,进而使用RxJava的各种操作符。
以下是一个使用Okhttp+Retrofit+RxJava获取百度天气的一个例子
//创建Retrofit
Retrofit retrofit=new Retrofit.Builder()
.baseUrl(WEATHERAPI)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
//RxJavaServcie是按照Retrofit格式创建的一个接口,用于将网络数据转化为实体类
RxJavaService service=retrofit.create(RxJavaService.class);
service.getServiceOfRx(
"北京",
"json",
"MymckXimfSdyGCmtlqbMoplcqibZtzdu",
"77:BD:E8:C4:B1:28:5A:26:8B:E8:F1:C0:CE:45:40:E1:E4:A1:12:FE;jiacc.justhabit"
).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Weather>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Weather weather) {
Weather.WeatherData data=weather.results.get(0).weather_data.get(0);
Picasso.with(mContext).load(data.dayPictureUrl).into(iv);
tv_weathers.setText(data.weather+" "+data.wind+" "+data.temperature);
tv_date.setText(data.date);
}
});
第四个例子:转换(Map操作符的使用)
//students的类型是List<Student>
Observable.from(students)
.map(new Func1<Student, String>() {//使用map依次将List的每个对象在回调方法中转为为student.name
@Override
public String call(Student student) {
return student.name;
}
})
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.i("jcc",s);
}
});
以上是一对一的转换,当一个学生有多门课程的时候,
Observable.from(students)
.flatMap(new Func1<Student, Observable<String>>() {
@Override
public Observable<String> call(Student student) {
return Observable.from((String[])student.courses);
}
})
.subscribe(new Observer<String>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
Log.i("jcc",e.getMessage());
}
@Override
public void onNext(String s) {
Log.i("jcc",s);
}
});
第五个例子:RxJava代替EventBus进行数据传递:RxBus
IM举例来说,服务器推送来消息,更新消息的方法有如下几个:
1. 只更新当前页面,如有其他页面在onCreate()的时候传入值更新
2. 设置广播事件。来消息的时候发送广播提示更新
3. 设置接口。
4. 使用观察者模式。也就是Eventbus以及Rxbus实现的功能,或者java中的Observable
上面的四种方式,
第一种差评,可以直接排除。
第二种,每条消息都要创建Intent,频繁的发广播
第三种,新房帮以前的就是类似这样做的,每个需要更新的页面都有一个refresh()方法,维护起来十分麻烦(这种也是最原始的观察者模式了,只是没有使用API那么好用)
因此,在这里就可以使用Eventbus或者Rxbus了。
http://blog.csdn.net/liuye066/article/details/53924957