使用RxJava、RxAndroid 、Lambda 也有一段时间了,这时我的第一篇发布的文章,希望对初学的程序员们有所帮助啦
(本片只讲用法,不说原理需要学习原理的话可以到 http://gank.io/post/560e15be2dca930e00da1083)
本人使用的 rx1 ,IDE工具 Android Studio 2.3 + JDK 1.8
1.首先需要在我们的 app的目录下面 build.gradle 配置
android{
defaultConfig{
// Lambda & Stream
jackOptions {
enabled true
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies{
// 1.RxJava RxAndroid
compile'io.reactivex:rxjava:1.1.0'
compile'io.reactivex:rxandroid:1.1.0'
compile'com.f2prateek.rx.preferences:rx-preferences:1.0.1'
compile'com.jakewharton.rxbinding:rxbinding:0.4.0'
compile'com.trello:rxlifecycle:0.4.0'
compile'com.trello:rxlifecycle-components:0.4.0'
// 2Lambda & Stream
compile'com.annimon:stream:1.1.5'
}
2.在项目的build.greadle 下 加入
classpath'me.tatarka:gradle-retrolambda:3.5.0' // Add By Howe - Lambda
如:
dependencies {
classpath'com.android.tools.build:gradle:2.3.0'
classpath'me.tatarka:gradle-retrolambda:3.5.0' // Add By Howe - Lambda
}
好啦,android 和 Lambda 的属性就此配置完成啦
看一下效果图
这里详细介绍了如何运用 RxJava 创建数据,使用数据,筛选数据,替换数据
调用数据的三大常用方法:create、from、just
数据筛选的常用方法:map、flatMap、filter、lift、compose
1)创建方法:Observable.create
Observable.create(new Observable.OnSubscribe() {
@Override
public void call(Subscriber subscriber) {
subscriber.onNext("Hello");
subscriber.onNext("Hi");
subscriber.onNext("Aloha");
subscriber.onCompleted();
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer() {
Stringtext ="";
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String s) {
}
});
很简单的一个创建方法,
可以看到,这里传入了一个 OnSubscribe 对象作为参数。OnSubscribe 会被存储在返回的 Observable 对象中,它的作用相当于一个计划表,当 Observable 被订阅的时候,OnSubscribe 的 call() 方法会自动被调用,事件序列就会依照设定依次触发(对于上面的代码,就是观察者Subscriber 将会被调用三次 onNext() 和一次 onCompleted())。这样,由被观察者调用了观察者的回调方法,就实现了由被观察者向观察者的事件传递,即观察者模式。
2) 方法 from
String[]words = {"Hello", "Hi", "Aloha", "", null, "最后"};
// from : 数据可以切换,不一定说传什么就返回什么
Observable.from(words)
// 判断是否存在
// .exists(i -> StringUtils.isNotEmpty(i))
// 判断是否存在
// .map((Func1) s -> StringUtils.isNotEmpty(s));
.map(new Func1() {
@Override
public Integer call(String s) {
return StringUtils.isNotEmpty(s) ?0 :1;
}
})
// lambda 表达式
//.lift((Observable.Operator) subscriber -> new Subscriber() {
// 替换/转换对象
.lift(new Observable.Operator() {
@Override
public Subscriber call(Subscriber subscriber) {
return new Subscriber() {
@Override
public void onCompleted() { }
@Override
public void onError(Throwable e) { }
@Override
public void onNext(Integer integer) {
subscriber.onNext("" + integer);
}
};
}
})
.subscribe(new Action1() {
String text ="";
@Override
public void call(String s) {
text += s;
mText.setText(text);
}
});
效果图如下:
3)方法 just
int[] data1 = {11,12,13,14,15,16,17,18,19};
int[] data2 = {21,22,23,24,25,26,27,28,29};
int[] data3 = {31,32,33,34,35,36,37,38,39};
// just: 传什么返回什么,需要用 替换/转换的方法转类型
Observable.just(data1, data2, data3)
.filter(new Func1() {
@Override
public Boolean call(int[] ints) {
return ints.length >0;
}
})
.flatMap(new Func1>() {
@Override
public Observable call(int[] ints) {
// 不能在用just:否则我不能拆分数组
return Observable.from(getStringCom(ints));// 转成 String[] 类型
}
})
// 可要可无
.lift(new Observable.Operator() {
@Override
public Subscriber call(Subscriber subscriber) {
return new Subscriber() {
@Override
public void onCompleted() { }
@Override
public void onError(Throwable e) { }
@Override
public void onNext(String s) {
subscriber.onNext(s);
}
};
}
})
// 上加了线程切换会和上面的lift的观察者发生交集错误
// .subscribeOn(Schedulers.io())
// .observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1() {
Stringtext ="";
@Override
public void call(String str) {
text +="\n" + str;
mText.setText(text);
}
});
输出结果(都是换行的):11,12,13,14,15,16,17,18,19,21,22,23,24,25,26,27,28,29,31,32,33,34,35,36,37,38,39
// lambda 表达式写法
Observable.just(data1, data2, data3)
.filter(i -> i.length >0)
.flatMap(ints -> Observable.from(getStringCom(ints)))
.lift((Observable.Operator) subscriber ->new Subscriber() {
@Override
public void onCompleted() { }
@Override
public void onError(Throwable e) { }
@Override
public void onNext(String s) {
subscriber.onNext(s);
}
})
// 上加了线程切换会和上面的lift的观察者发生交集错误
// .subscribeOn(Schedulers.io())
// .observeOn(AndroidSchedulers.mainThread())
.subscribe(s -> mText.setText(s));
效果图:使用 just 方法创建 被观察者,如果没有替换数据的话,你传什么就返回什么的,代码里面的注释已经说的很清楚啦
4)Map 和 flatMap
原理:http://blog.csdn.net/new_abc/article/details/48025513
Drawable[] b = {getResources().getDrawable(R.mipmap.icon1), getResources().getDrawable(R.mipmap.icon1)};
Observable.from(b)
// 筛选 方法 从上往下 执行
.flatMap(new Func1>() {
@Override
public Observablecall(Drawable bitmap) {
// Toast.makeText(TwoRxJavaActivity.this, "哈哈哈哈哈", Toast.LENGTH_SHORT).show(); // 添加了这句话.subscribeOn(Schedulers.io())已经是主线程之外的方法了
return Observable.from(new Drawable[]{bitmap});
}
})
.filter(i -> i !=null)
.map(new Func1() {
@Override
public Bitmapcall(Drawable drawable) {
BitmapDrawable bd = (BitmapDrawable) drawable;
Bitmap bm = bd.getBitmap();
return bm;
}
})
// 把加载图片的处理放在主线程之外,可以防止短时间的卡顿,让用户使用app更加的随心应手
.subscribeOn(Schedulers.io())// 指定 subscribe() 发生在 IO 线程:所以 flatMap、filter、map都会发生在主线程之外,不能更新界面信息
.observeOn(AndroidSchedulers.mainThread())// // 指定 Subscriber 的回调发生在主线程:所以 new 出来的 观察则 都会发生在主线程中
.subscribe(new Action1() {
@Override
public void call(Bitmap bitmap) {
Toast.makeText(TwoRxJavaActivity.this, "哈哈哈哈哈", Toast.LENGTH_SHORT).show();
mImg.setImageBitmap(bitmap);
}
});
效果图:
Map 和 flatMap 都有替换的功能,不过Map 只是一对一关系,而 flatMap 有一对多,所以相对更强大好用
5)方法 filter
主要作用就是判断,返回值是 Boolean
int[] data = {1,2,3,4,5,6,7,8,9,0};
// filter 返回 true/false
Observable.just(data)
// 判断 数组 data 的长度大于0
.filter(i -> i.length >0)
// .flatMap((Func1>) ints -> Observable.from(getStringCom(ints))) // lambda 表达式
// 转换成 String[] 类型,然后用from 一个一个的读取出来
.flatMap(new Func1>() {
@Override
public Observable call(int[] ints) {
return Observable.from(getStringCom(ints));
}
})
// 判断 是否是偶数取值
.filter(i -> Integer.valueOf(i) %2 ==0)
.subscribe(new Action1() {
Stringtext ="";
@Override
public void call(String s) {
text +="\n" + s;
mText.setText(text);
}
});
结果:2,4,6,8,0
效果图:
6)方法 lift
String[]words = {"Hello", "Hi", "Aloha", "", null, "最后"};
// from : 数据可以切换,不一定说传什么就返回什么
Observable.from(words)
// 判断是否存在
// .exists(i -> StringUtils.isNotEmpty(i))
// 判断是否存在
// .map((Func1) s -> StringUtils.isNotEmpty(s));
.map(new Func1() {
@Override
public Integer call(String s) {
return StringUtils.isNotEmpty(s) ?0 :1;
}
})
// lambda 表达式
//.lift((Observable.Operator) subscriber -> new Subscriber() {
// 替换/转换对象
.lift(new Observable.Operator() {
@Override
public Subscriber call(Subscriber subscriber) {
return new Subscriber() {
@Override
public void onCompleted() { }
@Override
public void onError(Throwable e) { }
@Override
public void onNext(Integer integer) {
subscriber.onNext("" + integer);
}
};
}
})
.subscribe(new Action1() {
String text ="";
@Override
public void call(String s) {
text += s;
mText.setText(text);
}
});
效果图如下:
7)方法 compose
compose: 对 Observable 整体的变换
除了 lift() 之外, Observable 还有一个变换方法叫做 compose(Transformer)。它和 lift() 的区别在于, lift() 是针对事件项和事件序列的,而 compose() 是针对 Observable 自身进行变换。举个例子,假设在程序中有多个 Observable ,并且他们都需要应用一组相同的 lift() 变换。你可以这么写:
observable1
.lift1()
.lift2()
.lift3()
.lift4()
.subscribe(subscriber1);
observable2
.lift1()
.lift2()
.lift3()
.lift4()
.subscribe(subscriber2);
observable3
.lift1()
.lift2()
.lift3()
.lift4()
.subscribe(subscriber3);
observable4
.lift1()
.lift2()
.lift3()
.lift4()
.subscribe(subscriber1);
你觉得这样太不软件工程了,于是你改成了这样:
private Observable liftAll(Observable observable) {
return observable
.lift1()
.lift2()
.lift3()
.lift4();
}
...
liftAll(observable1).subscribe(subscriber1);
liftAll(observable2).subscribe(subscriber2);
liftAll(observable3).subscribe(subscriber3);
liftAll(observable4).subscribe(subscriber4);
可读性、可维护性都提高了。可是 Observable 被一个方法包起来,这种方式对于 Observale 的灵活性似乎还是增添了那么点限制。怎么办?这个时候,就应该用 compose() 来解决了:
public class LiftAllTransformerimplements Observable.Transformer {
@Override
public Observable call(Observable observable) {
return observable
.lift1()
.lift2()
.lift3()
.lift4();
}
}
...
Transformer liftAll =new LiftAllTransformer();
observable1.compose(liftAll).subscribe(subscriber1);
observable2.compose(liftAll).subscribe(subscriber2);
observable3.compose(liftAll).subscribe(subscriber3);
observable4.compose(liftAll).subscribe(subscriber4);
像上面这样,使用 compose() 方法,Observable 可以利用传入的 Transformer 对象的 call 方法直接对自身进行处理,也就不必被包在方法的里面了。
谢谢大哥们的观赏,小弟初来乍到,有什么错误谢谢指导,感激不尽
网友评论