RxJava2 實(shí)戰(zhàn)系列文章
RxJava2 實(shí)戰(zhàn)知識(shí)梳理(1) - 后臺(tái)執(zhí)行耗時(shí)操作,實(shí)時(shí)通知 UI 更新
RxJava2 實(shí)戰(zhàn)知識(shí)梳理(2) - 計(jì)算一段時(shí)間內(nèi)數(shù)據(jù)的平均值
RxJava2 實(shí)戰(zhàn)知識(shí)梳理(3) - 優(yōu)化搜索聯(lián)想功能
RxJava2 實(shí)戰(zhàn)知識(shí)梳理(4) - 結(jié)合 Retrofit 請(qǐng)求新聞資訊
RxJava2 實(shí)戰(zhàn)知識(shí)梳理(5) - 簡單及進(jìn)階的輪詢操作
RxJava2 實(shí)戰(zhàn)知識(shí)梳理(6) - 基于錯(cuò)誤類型的重試請(qǐng)求
RxJava2 實(shí)戰(zhàn)知識(shí)梳理(7) - 基于 combineLatest 實(shí)現(xiàn)的輸入表單驗(yàn)證
RxJava2 實(shí)戰(zhàn)知識(shí)梳理(8) - 使用 publish + merge 優(yōu)化先加載緩存,再讀取網(wǎng)絡(luò)數(shù)據(jù)的請(qǐng)求過程
RxJava2 實(shí)戰(zhàn)知識(shí)梳理(9) - 使用 timer/interval/delay 實(shí)現(xiàn)任務(wù)調(diào)度
RxJava2 實(shí)戰(zhàn)知識(shí)梳理(10) - 屏幕旋轉(zhuǎn)導(dǎo)致 Activity 重建時(shí)恢復(fù)任務(wù)
RxJava2 實(shí)戰(zhàn)知識(shí)梳理(11) - 檢測網(wǎng)絡(luò)狀態(tài)并自動(dòng)重試請(qǐng)求
RxJava2 實(shí)戰(zhàn)知識(shí)梳理(12) - 實(shí)戰(zhàn)講解 publish & replay & share & refCount & autoConnect
RxJava2 實(shí)戰(zhàn)知識(shí)梳理(13) - 如何使得錯(cuò)誤發(fā)生時(shí)不自動(dòng)停止訂閱關(guān)系
RxJava2 實(shí)戰(zhàn)知識(shí)梳理(14) - 在 token 過期時(shí),刷新過期 token 并重新發(fā)起請(qǐng)求
RxJava2 實(shí)戰(zhàn)知識(shí)梳理(15) - 實(shí)現(xiàn)一個(gè)簡單的 MVP + RxJava + Retrofit 應(yīng)用
一、前言
今天,我們繼續(xù)跟著 RxJava-Android-Samples 的腳步,一起看一下RxJava2
在實(shí)戰(zhàn)當(dāng)中的應(yīng)用,在這個(gè)項(xiàng)目中,第二個(gè)的例子的描述如下:
簡單地翻譯過來:如果在
2s
內(nèi)連續(xù)點(diǎn)擊了一個(gè)按鈕五次,那么我們只會(huì)收到一個(gè)“你點(diǎn)擊了該按鈕五次”的時(shí)間,而不是五個(gè)"你點(diǎn)擊了該按鈕"的事件。這個(gè)示例的目的是讓我們學(xué)會(huì)如何應(yīng)用buffer
操作符。
二、示例
2.1 應(yīng)用場景
仔細(xì)思考了一下,在平時(shí)的項(xiàng)目中,我們似乎不會(huì)遇到需要統(tǒng)計(jì)一段時(shí)間內(nèi)用戶點(diǎn)擊了多少次按鈕這種需求。
但是,我們有時(shí)候會(huì)需要計(jì)算一段時(shí)間內(nèi)的平均數(shù)據(jù),例如統(tǒng)計(jì)一段時(shí)間內(nèi)的平均溫度,或者統(tǒng)計(jì)一段時(shí)間內(nèi)的平均位置。在接觸RxJava
之前,我們一般會(huì)將這段時(shí)間內(nèi)統(tǒng)計(jì)到的數(shù)據(jù)都暫時(shí)存起來,等到需要更新的時(shí)間點(diǎn)到了之后,再把這些數(shù)據(jù)結(jié)合起來,計(jì)算這些數(shù)據(jù)的平均值。
現(xiàn)在,我們就來看一下,用RxJava2
如何去實(shí)現(xiàn)這個(gè)需求。
2.2 示例代碼
這里,我們通過一個(gè)Handler
循環(huán)地發(fā)送消息,實(shí)現(xiàn)間隔一定時(shí)間進(jìn)行溫度的測量,但是在測量之后,我們并不實(shí)時(shí)地更新界面的溫度顯示,而是每隔3s
統(tǒng)計(jì)一次過去這段時(shí)間內(nèi)的平均溫度。
public class BufferActivity extends AppCompatActivity {
private PublishSubject<Double> mPublishSubject;
private CompositeDisposable mCompositeDisposable;
private TextView mTv;
private SourceHandler mSourceHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_buffer);
mTv = (TextView) findViewById(R.id.tv_buffer);
mPublishSubject = PublishSubject.create();
DisposableObserver<List<Double>> disposableObserver = new DisposableObserver<List<Double>>() {
@Override
public void onNext(List<Double> o) {
double result = 0;
if (o.size() > 0) {
for (Double d : o) {
result += d;
}
result = result / o.size();
}
Log.d("BufferActivity", "更新平均溫度:" + result);
mTv.setText("過去3秒收到了" + o.size() + "個(gè)數(shù)據(jù), 平均溫度為:" + result);
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onComplete() {
}
};
mPublishSubject.buffer(3000, TimeUnit.MILLISECONDS).observeOn(AndroidSchedulers.mainThread()).subscribe(disposableObserver);
mCompositeDisposable = new CompositeDisposable();
mCompositeDisposable.add(disposableObserver);
//開始測量溫度。
mSourceHandler = new SourceHandler();
mSourceHandler.sendEmptyMessage(0);
}
public void updateTemperature(double temperature) {
Log.d("BufferActivity", "溫度測量結(jié)果:" + temperature);
mPublishSubject.onNext(temperature);
}
private class SourceHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
double temperature = Math.random() * 25 + 5;
updateTemperature(temperature);
//循環(huán)地發(fā)送。
sendEmptyMessageDelayed(0, 250 + (long) (250 * Math.random()));
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mSourceHandler.removeCallbacksAndMessages(null);
mCompositeDisposable.clear();
}
}
實(shí)際的運(yùn)行結(jié)果為:
控制臺(tái)輸出的信息為:
三、示例解析
3.1 原理
在上面的例子中,我們使用了buffer(int time, Unit timeUnit)
,其原理圖如下所示:
函數(shù)中的兩個(gè)形參分別對(duì)應(yīng)是時(shí)間的值和單位,這樣,當(dāng)我們通過下面這句發(fā)送事件:
mPublishSubject.onNext(temperature);
事件并不會(huì)直接傳遞到Observer
的onNext
方法中,而是放在緩沖區(qū)中,直到事件到之后,再將所有在這段緩沖事件內(nèi)放入緩沖區(qū)中的值,放在一個(gè)List
中一起發(fā)送到下游。
3.2 Buffer 的其它用法
關(guān)于Buffer
的其它用法,這篇文章寫得很全,我這里就不詳細(xì)贅述了,大家可以參考:RxJava 的學(xué)習(xí)之變換操作符 - Buffer。
四、參考文獻(xiàn)
RxJava 的學(xué)習(xí)之變換操作符 - Buffer
更多文章,歡迎訪問我的 Android 知識(shí)梳理系列:
- Android 知識(shí)梳理目錄:http://www.lxweimin.com/p/fd82d18994ce
- 個(gè)人主頁:http://lizejun.cn
- 個(gè)人知識(shí)總結(jié)目錄:http://lizejun.cn/categories/