RX
1. buffer
Buffer官方介紹
操作符將一個Observable變換為另一個共啃,原來的Observable正常發(fā)射數(shù)據(jù)环戈,變換產(chǎn)生的Observable發(fā)射這些數(shù)據(jù)的緩存集合次和。Buffer
操作符在很多語言特定的實現(xiàn)中有很多種變體裙士,它們在如何緩存這個問題上存在區(qū)別。
buffer(int count)
緩存一定數(shù)量的信息后才打包一起發(fā)送,打包后是以List<T>
的形式發(fā)送米丘。buffer(int count ,int skip)
緩存一定數(shù)量的信息后才打包一起發(fā)送蚕甥,其中可以設(shè)定下一次的緩存開始位置,打包后是以List<T>
的形式發(fā)送炕舵。
測試代碼:構(gòu)建一個String數(shù)組何之,發(fā)布者(Observable)的行為是緩存 count 個消息并打包發(fā)送,訂閱者的行為是接受每個發(fā)送來的List并打印咽筋。
//數(shù)據(jù)源
String[] strs = {"a","b","c","d","e","f","g","h","i"};
//發(fā)布者
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);
result
可見是緩存兩個信息溶推,并且打包發(fā)出,而且下一次的緩存位置是在當(dāng)前緩存隊列的第1位(指的是下標)開始。
- count=2,skip=2
origin.buffer(2,2).subscribe(sub);
result
同樣是緩存了兩個信息蒜危,而下一次的緩存開始位置是在隊列的第2位(指的是下標虱痕,說明一下,這里的隊列是當(dāng)前還未發(fā)送的信息的隊列辐赞,之前已經(jīng)發(fā)送的是不算的)
- count=2,skip=3
origin.buffer(2,3).subscribe(sub);
result
c沒了部翘,f也沒了,i同樣消失了响委!
- 示意圖新思,幫助理解
示意圖.png
感覺buffer(int count ,int skip)
不如buffer(int count ,int nextHead)
好理解呢。
2. interval
簡介的官方介紹晃酒,簡單卻實用
創(chuàng)建一個按固定時間間隔發(fā)射整數(shù)序列的Observable
interval(long interval,TimeUnit timeunit)
interval(long delay,long interval,TimeUnit timeunit)
之前寫倒計時的控件都是用Handler或者Timer去做的表牢,現(xiàn)在有這個就可以很方便的寫出倒計時控件,下面是我寫的一個倒計時按鈕贝次。
可以看到里面倒計時時數(shù)字有抖動崔兴,是模擬器的問題,在真機上是不會的(親測)蛔翅。
e1.gif
e2.gif
/**
* 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();
}
}
};
}
/**
* 停止倒計時 恢復(fù)成最初樣子
*/
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。