先贴一下上一篇地址:RxJava(二)歪解
这个是对上一篇的一个延续,哈哈......
一、用来延时的
这里只说timer()和delay();
timer()有两种,timer(long delay, TimeUnit unit)和timer(long delay, TimeUnit unit, Scheduler scheduler)
两个参数的方法调用后其实还是要调用三个参数的方法,这中间会默认的第三个设置为Schedulers.computation()(这个计算指的是 CPU 密集型计算),对于android来讲重要的就是它是非主线程更新UI会异常,所以使用最好还是使用三个参数的方法,根据需求指定线程。
timer()会创建一个Long类型的Observable对象,而且固定的发送一个0L 到onNext(),源码如下:
@Override
public void call(final Subscriber<? super Long> child) {
Worker worker = scheduler.createWorker();
child.add(worker);
worker.schedule(new Action0() {
@Override
public void call() {
try {
child.onNext(0L);
} catch (Throwable t) {
Exceptions.throwOrReport(t, child);
return;
}
child.onCompleted();
}
}, time, unit);
}
timer()可以由Observable直接调用并创建出对象(这点跟delay()有很大的区别),接下来可以通过这个Observable对象来做文章了。
下面代码会用到.map()操作符,无所谓,很快就要说到它了,实现首页两秒跳过:
Observable.timer(2, TimeUnit.SECONDS).map(new Func1<Long, Object>() {
@Override
public Object call(Long aLong) {
startActivity(new Intent(OperatorActivity.this,MainActivity.class));
finish();
return null;
}
}).subscribe();
delay()有四个不同参的方法,这里只说和timer()类似的两个。
它跟timer()的区别不多,delay()的调用依赖有类型的Observable对象,这么说有点抽象,其实就是Observable.delay()这样写是不允许的,因为delay()做的是变换:
如果存在subscribeOn()和observerOn()方法,可以忽略第三个参数,如果没有,最好还是……否则……应该没啥大问题。万一出现线程问题,你就可以往这里考虑了;
上一段delay()实现首页三秒跳过的代码:
Observable.just("1")//Observable不能直接.delay()
.delay(3, TimeUnit.SECONDS)
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Intent intent = null;
if (MyApplication.getInstance().getUserId().equals("")){
intent = new Intent(WelcomeActivity.this,LoginActivity.class);
}else{
intent = new Intent(WelcomeActivity.this,PackageActivity.class);
}
startActivity(intent);
finish();
}
});
下面是一个timer()的延时4秒运行截图:
二、ActionX系列和FuncX系列
开始计划第二步说map()和flipMap()的,发现总是有这两个玩意,就先说这两个东西了。
怎么说呢,这两个系列其实就是三代人。
祖辈就一个Function类,仅仅是个接口,就是个约束作用。
父辈人挺多,Func0,Func1,Func2....Func9,FuncN和Action。
FuncX这些泛型接口家伙的X表示需要X+1个泛型参数,第一个泛型是返回值类型,剩下的全是参数,在call()方法中用到。有返回就选用FuncX系列按需处理。
Action继承了Function,在父辈中比较特殊,然后啥也没实现,只是作为一个新系列的约束。
子辈就是ActionX了,也都是些接口,X表示需要X个泛型参数,这些参数全部作为call()的参数参与实现。
如果这个时候站在Action的角度看整个继承结构,Function就是它爹,FuncX系列就是它的兄弟们,而ActionX就是它的儿子们。
总之就是要返回值,根据需要的参数X数量决定使用FuncX的匿名实现;
不需要返回值,根据需要的参数X数量决定使用ActionX的匿名实现;
其实在ActionX和FuncX下面还有一些继承关系,比较深入了,就不说了。
感觉这里既没有代码也没有图过意不去,随便搞个图吧
三、map()和flapMap()
就常用的角度来讲,它们两个的参数一样的都是Func1(即一个输入参数,一个输出/返回参数,不同在于一个返回基本简单类型,一个返回Observable<简单类型>)(注:flatMap()还有几种参数,比较复杂,这里不说)。
个人理解的区别:
map()打死它,它都只会做数据的类型上的变换,而且是一对一的,单纯的变换,最后会执行onNext和onComplated没特殊要求的时候用map转换时最省力。
flatMap()呢,最简单的区别可能就是可以针对的在某一步的位置定义特殊的onComplated()之类的方法;如果这一点我猜错了,那么他么的重要区别可能就是flatMap更灵活一些(flatMap有更多的同名不同参方法);
口说无凭,还是上两段代码吧,这大夏天够热的,想买个冰棍消消暑,一摸身上,只有5块钱,这糟了,物价飞涨的,万一买不起雪糕不就黑了吗?这里我们就模拟一下从5块钱到吃雪糕(不是直接吃5块钱)这个过程(map()实现):
Observable.just(5)//仅有的5块钱
.map(new Func1<Integer, String>() {//将钱换物
@Override
public String call(Integer integer) {
if (integer>3)//判断钱够不够买一个,通货膨胀加国际行情,最便宜的就这个价
return "icecream";//买到艾斯科瑞姆
else
return "qiongbi";//被嘲讽
}
})
.map(new Func1<String, String>() {//将物消费
@Override
public String call(String s) {
if(s.equals("icecream"))//判断上一波的购买结果
return "I get it";//成功吃到
else
return "esidiele";//不禁感慨
}
})
.subscribe(new Observer<String>() {
@Override
public void onCompleted() {
Toast.makeText(mContext,"完成",Toast.LENGTH_SHORT).show();
}
@Override
public void onError(Throwable e) {
Toast.makeText(mContext,"出现异常",Toast.LENGTH_SHORT).show();
}
@Override
public void onNext(String s) {
Toast.makeText(mContext,s,Toast.LENGTH_SHORT).show();
}
});
就是这样,雪糕也吃完了,突然我又有了10块钱(高温补贴,羡慕吗?我也羡慕!!)接下来用flapMap()实现一下计算自己还能买多少的功能(好特么扯淡的功能):
Observable.just(10)//十元人民币,幼!呦!呦!天晴了雨停了你又......
.flatMap(new Func1<Integer, Observable<String>>() {
@Override
public Observable<String> call(Integer integer) {
int a = integer/3;
int b = integer%3;
String result = "我的钱够买" + a + "支雪糕,还剩" + b + "元";
return Observable.just(result);
}
})
.subscribe(new Observer<String>() {
@Override
public void onCompleted() {
Toast.makeText(mContext,"完成",Toast.LENGTH_SHORT).show();
}
@Override
public void onError(Throwable e) {
Toast.makeText(mContext,"出现异常",Toast.LENGTH_SHORT).show();
}
@Override
public void onNext(String s) {
Toast.makeText(mContext,s,Toast.LENGTH_SHORT).show();
}
});
上面两段代码的执行效果:
感觉到了这里,Rxjava的基本使用(就说基本使用)不成问题了,Rxjava还拥有大量的操作符,有些我还没琢磨呢,推荐一个学习操作符的系列文章,点击直通:第一篇地址
demo 下载地址