1. buffer
Buffer官方介绍
操作符将一个Observable变换为另一个,原来的Observable正常发射数据,变换产生的Observable发射这些数据的缓存集合。Buffer
操作符在很多语言特定的实现中有很多种变体,它们在如何缓存这个问题上存在区别。
buffer(int count)
缓存一定数量的信息后才打包一起发送,打包后是以List<T>
的形式发送。buffer(int count ,int skip)
缓存一定数量的信息后才打包一起发送,其中可以设定下一次的缓存开始位置,打包后是以List<T>
的形式发送。
测试代码:构建一个String数组,发布者(Observable)的行为是缓存 count 个消息并打包发送,订阅者的行为是接受每个发送来的List并打印。
//数据源
String[] strs = {"a","b","c","d","e","f","g","h","i"};
//发布者
Observable<String> origin = Observable.from(strs);
//订阅者
Subscriber<String> sub = new Subscriber<String>() {
@Override
public void onCompleted() {
Log.d("log", "Completed");
}
@Override
public void onError(Throwable e) {
Log.d("log", "Error");
}
@Override
public void onNext(String s) {
Log.d("log", "Next--------");
for (int i = 0 ; i < s.size();i++){
Log.d("log", s.get(i));
}
}
};
- count=2,skip=1
origin.buffer(2,1).subscribe(sub);
可见是缓存两个信息,并且打包发出,而且下一次的缓存位置是在当前缓存队列的第1位(指的是下标)开始。
- count=2,skip=2
origin.buffer(2,2).subscribe(sub);
同样是缓存了两个信息,而下一次的缓存开始位置是在队列的第2位(指的是下标,说明一下,这里的队列是当前还未发送的信息的队列,之前已经发送的是不算的)
- count=2,skip=3
origin.buffer(2,3).subscribe(sub);
c没了,f也没了,i同样消失了!
- 示意图,帮助理解
感觉buffer(int count ,int skip)
不如buffer(int count ,int nextHead)
好理解呢。
2. interval
简介的官方介绍,简单却实用
创建一个按固定时间间隔发射整数序列的Observable
interval(long interval,TimeUnit timeunit)
interval(long delay,long interval,TimeUnit timeunit)
之前写倒计时的控件都是用Handler或者Timer去做的,现在有这个就可以很方便的写出倒计时控件,下面是我写的一个倒计时按钮。
可以看到里面倒计时时数字有抖动,是模拟器的问题,在真机上是不会的(亲测)。
/**
* Created by ZhengHy on 2016/6/30 0030.
* 倒计时Button
*/
public class CountDownButton extends Button{
/**
* 默认倒计时时间
*/
private final int DEFAULT_COUNT = 60;
/**
* 倒计时时间
*/
private int iTotalCount = DEFAULT_COUNT;
private int iCountingNum = DEFAULT_COUNT;
/**
* 默认开始显示的字符串
*/
private final String DEFAULT_START_STR = "开始";
/**
* 开始显示的字符串
*/
private String sStartStr = DEFAULT_START_STR;
/**
* 等待颜色
*/
private int normalColor = 0xffff4000;
/**
* 倒计时颜色
*/
private int countingColor = 0xffffffff;
/**
* 倒计时订阅者
*/
private Subscriber<Long> countDownTimer;
public CountDownButton(Context context) {
super(context);
init();
}
public CountDownButton(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CountDownButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
onPre();
}
public int getiTotalCount() {
return iTotalCount;
}
public void setiTotalCount(int iTotalCount) {
this.iTotalCount = iTotalCount;
this.iCountingNum = iTotalCount;
}
/**
* 开始倒计时
*/
public void countDown() {
initTimer();
onCounting();
Observable.interval(0, 1, TimeUnit.SECONDS)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(countDownTimer);
}
private void initTimer() {
countDownTimer = new Subscriber<Long>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Long aLong) {
iCountingNum--;
setText(iCountingNum + "");
if (iCountingNum == 0l) {
countDownTimer.unsubscribe();
setClickable(true);
onPre();
}
}
};
}
/**
* 停止倒计时 恢复成最初样子
*/
public void shutDown() {
if (countDownTimer != null) {
countDownTimer.unsubscribe();
onPre();
}
}
private void onPre() {
setClickable(true);
iCountingNum = iTotalCount;
setText(sStartStr);
setTextColor(normalColor);
}
private void onCounting() {
setClickable(false);
setTextColor(countingColor);
}
}
页面布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<Button
android:text="shutdown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/cdb"
android:layout_alignEnd="@+id/cdb"
android:layout_marginTop="20dp"
android:id="@+id/btn" />
<network.scau.com.countdownbuttondemo.CountDownButton
android:background="#ff000000"
android:id="@+id/cdb"
android:layout_width="100dp"
android:layout_height="50dp"
android:gravity="center"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
MainActivity,使用ButterKnife注入控件
public class MainActivity extends AppCompatActivity {
@Bind(R.id.btn)
Button btn;
@Bind(R.id.cdb)
CountDownButton cdb;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
}
@OnClick(R.id.cdb)
public void countting() {
Toast.makeText(this,"countting",Toast.LENGTH_LONG).show();
cdb.countDown();
}
@OnClick(R.id.btn)
public void shutdown(){
Toast.makeText(this,"shutdown",Toast.LENGTH_LONG).show();
cdb.shutDown();
}
}
有趣的Rx。