一、前言
今天,我們繼續跟著 RxJava-Android-Samples 的腳步,一起看一下RxJava2
在實戰當中的應用,在這個專案中,第二個的例子的描述如下:
2s
內連續點選了一個按鈕五次,那麼我們只會收到一個“你點選了該按鈕五次”的時間,而不是五個"你點選了該按鈕"的事件。這個示例的目的是讓我們學會如何應用buffer
操作符。
二、示例
2.1 應用場景
仔細思考了一下,在平時的專案中,我們似乎不會遇到需要統計一段時間內使用者點選了多少次按鈕這種需求。
但是,我們有時候會需要計算一段時間內的平均資料,例如統計一段時間內的平均溫度,或者統計一段時間內的平均位置。在接觸RxJava
之前,我們一般會將這段時間內統計到的資料都暫時存起來,等到需要更新的時間點到了之後,再把這些資料結合起來,計算這些資料的平均值。
現在,我們就來看一下,用RxJava2
如何去實現這個需求。
2.2 示例程式碼
這裡,我們通過一個Handler
迴圈地傳送訊息,實現間隔一定時間進行溫度的測量,但是在測量之後,我們並不實時地更新介面的溫度顯示,而是每隔3s
統計一次過去這段時間內的平均溫度。
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() + "個資料, 平均溫度為:" + 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", "溫度測量結果:" + 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);
//迴圈地傳送。
sendEmptyMessageDelayed(0, 250 + (long) (250 * Math.random()));
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mSourceHandler.removeCallbacksAndMessages(null);
mCompositeDisposable.clear();
}
}
複製程式碼
實際的執行結果為:
控制檯輸出的資訊為:三、示例解析
3.1 原理
在上面的例子中,我們使用了buffer(int time, Unit timeUnit)
,其原理圖如下所示:
mPublishSubject.onNext(temperature);
複製程式碼
事件並不會直接傳遞到Observer
的onNext
方法中,而是放在緩衝區中,直到事件到之後,再將所有在這段緩衝事件內放入緩衝區中的值,放在一個List
中一起傳送到下游。
3.2 Buffer 的其它用法
關於Buffer
的其它用法,這篇文章寫得很全,我這裡就不詳細贅述了,大家可以參考:RxJava 的學習之變換操作符 - Buffer。
四、參考文獻
更多文章,歡迎訪問我的 Android 知識梳理系列:
- Android 知識梳理目錄:www.jianshu.com/p/fd82d1899…
- 個人主頁:lizejun.cn
- 個人知識總結目錄:lizejun.cn/categories/