RxJava 常用操作符大全(二)

时间:2021-09-07 14:19:12

RxJava 常用操作符大全(二)

ThrottleFirst巧妙使用

防止View被连续点击,仅发送指定时间段内的第一个信号

RxView.clicks(btThrottleFirst)
.throttleFirst(3, TimeUnit.SECONDS)
.subscribe(new Action1<Void>() {
@Override
public void call(Void aVoid) {
Toast.makeText(mContext, "我是一个在3秒内不会被重复点击的按钮", Toast.LENGTH_SHORT).show();
}
        });

PublishSubject

与普通的Subject不同,在订阅时并不立即触发订阅事件,而是允许我们在任意时刻手动调用onNext(),onError(),onCompleted来触发事件。

可以看到PublishSubject与普通的Subject最大的不同就是其可以先订阅事件,然后在某一时刻手动调用方法来触发事件,那么拿他又能做些什么?

举个例子:当一个界面发生改变,通知另一个界面做出响应,以下是两个Fragment之间通讯的Demo

1、首先在外部定义好公共的PublishSubject对象

PublishSubject<String> publishSubject = PublishSubject.create();
PublishSubjectTopFragment topFragment = new PublishSubjectTopFragment(publishSubject);
PublishSubjectBottomFragment bottom_Fragment = new PublishSubjectBottomFragment(publishSubject);
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fl_top,topFragment, "top")
.replace(R.id.fl_bottom, bottom_Fragment, "bottom")
.commit();
}

2、TopFragment中负责发出信息

@OnClick(R.id.btn_send)
void sendToBottom(){
String result = et_input.getText().toString().trim();
/** *在这一时刻手动调用方法来触发事件: * 发出信息 */
publishSubject.onNext(result);
}

3、BottomFragment中接收到通知后,产生响应

/** * 这里先订阅事件: * 接收到通知后,产生响应 * */
publishSubject.subscribe(new Action1<String>() {
@Override
public void call(String s) {
tv_result.setText("收到上级的秘密召令:"+s);
}
});

Buffer

buffer(count = 3):

Buffer操作符所要做的事情就是将数据安装规定的大小做一下缓存,然后将缓存的数据作为一个集合发射出去。

buffer(count = 2, skip = 3):

    skip参数用来指定每次发射一个集合需要跳过几个数据,指定的count为2,skip为3,就会每3个数据发射一个包含两个数据的集合,如果count==skip的话,其就会等效于 buffer(count = 3) 了。

Scan

Scan操作符对一个序列的数据应用一个函数,并将这个函数的结果发射出去作为下个数据应用这个函数时候的第一个参数使用,有点类似于递归操作

Observable.just(1,2,3,4,5)
.scan(new Func2<Integer, Integer, Integer>() {
@Override
public Integer call(Integer integer, Integer integer2) {
return integer*integer2;
}
        }).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
tvResult.append(integer+"\n");
}
});

Distinct

Distinct操作符的用处就是用来去重,非常好理解,所有重复的数据都会被过滤掉。

Observable.just(1,2,3,1,1,2,1,4,5)
.distinct()
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
tvResult.append(integer+"");
}
        });

而操作符DistinctUntilChanged则是用来过滤掉连续的重复数据。

Observable.just(1, 2, 3, 3, 3, 1, 2, 3, 3).distinctUntilChanged();

Filter

只会返回满足过滤条件的数据

Observable.just(1,2,3,4,5)
.filter(new Func1<Integer, Boolean>() {
@Override
public Boolean call(Integer integer) {
return integer>=3;
}
        }).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
tvResult.append("被筛选过的战斗力大于等于3的大神们是:"+integer);
}
});

Skip、Take

Skip操作符将源Observable发射的数据过滤掉前n项

Take操作符则只取前n项,理解和使用起来都很容易,但是用处很大。另外还有

SkipLast和TakeLast操作符,分别是从后面进行过滤操作

Observable.just("我","不","我","是","大","帅","锅")
.skip(2)
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
tvResult.append(s);
}
        });

Publish

什么是Connectable Observable?

就是一种特殊的Observable对象,并不是Subscrib的时候就发射数据,而是只有对其应用connect操作符的时候才开始发射数据,所以可以用来更灵活的控制数据发射的时机。

而Publish操作符就是用来将一个普通的Observable对象转化为一

个Connectable Observable。需要注意的是如果发射数据已经开始

了再进行订阅只能接收以后发射的数据

Connect

Connect操作符就是用来触发Connectable Observable发射数据的。

应用Connect操作符后会返回一个Subscription对象,通过这个Subscription对象,我们可以调用其unsubscribe方法来终止数据的发射。

另外,如果还没有订阅者订阅的时候就应用Connect操作符也是可以使其开始发射数据的。

使用

先使用publish操作符创建一个Connectable Observable:

private ConnectableObservable<Long> publishObserver() {
Observable<Long> obser = Observable.interval(1, TimeUnit.SECONDS);
obser.observeOn(Schedulers.newThread());
    return obser.publish();
}

然后创建两个Action1对象,在不同的时机对其进行订阅:

ConnectableObservable<Long> obs = publishObserver();
Action1 action2 = o -> log("action2:" + o);
Action1 action1 = o -> {
log("action1:" + o);
    if ((long) o == 3) obs.subscribe(action2);
};
obs.subscribe(action1);

mLButton.setText("start");
mLButton.setOnClickListener(e -> mSubscription = obs.connect());
mRButton.setText("stop");
mRButton.setOnClickListener(e -> {
if (mSubscription != null) {
mSubscription.unsubscribe();
}
});

当点击start按钮的时候对这个Connectable Observable 对象应用
connect操作符,让其开始发射数据。

当发射到3的时候将action2给订阅上,这个两个订阅者将同时收到相同的数据。点击stop按钮的时候终止其数据的发射。

RefCount

RefCount操作符就是将一个Connectable Observable 对象再重新转化为一个普通的Observable对象。

说点什么吧

RxJava 常用操作符大全(二)

天啊,不知不觉,就完了啊。我的天,一个月啊,一个月前计划的学习这些东西开始,到现在,居然到头来发现,好像不是很多,又感觉挺满足的了,好气啊。

本身就喜欢去学习一些好玩的东西,所以,平时不是很忙的时候,都喜欢去默默踩一下坑,慢慢再填上去。

这些操作符主要太简单,所以大部分的很多注释和点我都注释写在了代码里面,Demo在这,有兴趣的可以。。。。额,害羞的说一下,有兴趣的可以来逛逛,万一有啥合适的呢,缘分这种东西很难说的~~
https://github.com/GitHuborz/RxJavaOPDemo

月学习计划总结

这一阵子,也是告一小段落了。

一个月前,准备了这个月的学习计划,着手学习新知识,RxJava,Retrofit等等的这些。从刚开始听着就觉得很屌的东西,从开始谷歌搜索资料,再慢慢一点点看下去,记下笔记和编写Demo,感受这
些主流框架开源库的强大和魅力之处,虽然现在做APP的机会不多,但有关这些的新科技还是时不时更新一下,学习多点,还是很棒的。

然后,这周主要是系统的学习了一番Rx 的我觉得实用的,也常有的操作符,学一个,写一个Demo测试跟上,加上自己的理解,基本我觉得这些也就够日常用了吧,至于不够的,还可以自定义操作符呢,是吧。
O(∩_∩)O~

这段是时间的学习,也整理了一大部分笔记,准备整理一下,小更新一下C博客(RXJava(系列),好久都没动了 ~都存在了云笔记,没办法,懒。。

这次主要学习的内容,都有记录下笔记,也都编写对应的Demo,基本就这些了:
**1、MvpDemo (一个简单的MVP架构的demo)
2、RetrofitRxJavaDemo (一个使用RxJava + Retrofit 的小demo)**
https://github.com/GitHuborz/MvpDemo-RetrofitRxJvaDemo

一个基于 RxJava+Retrofit+Mvp+… 的浏览Gank. 的妹子的学习小Demo
https://github.com/GitHuborz/MeiZi

RxJava 的所有常用操作符详解+使用Demo
https://github.com/GitHuborz/RxJavaOPDemo

害羞(✿◡‿◡)~RxJava 常用操作符大全(二)