一、Scheduler執行緒切換
這種場景經常會在“後臺執行緒取資料,主執行緒展示”的模式中看見
-
Observable.just(1, 2, 3, 4)
-
.subscribeOn(Schedulers.io()) // 指定 subscribe() 發生在 IO 執行緒
-
.observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回撥發生在主執行緒
-
.subscribe(new Action1<Integer>() {
-
@Override
-
public void call(Integer number) {
-
Log.d(tag, "number:" + number);
-
}
-
});
二、使用debounce做textSearch
用簡單的話講就是當N個結點發生的時間太靠近(即發生的時間差小於設定的值T),debounce就會自動過濾掉前N-1個結點。
比如在做百度地址聯想的時候,可以使用debounce減少頻繁的網路請求。避免每輸入(刪除)一個字就做一次聯想
-
RxTextView.textChangeEvents(inputEditText)
-
.debounce(400, TimeUnit.MILLISECONDS)
-
.observeOn(AndroidSchedulers.mainThread())
-
.subscribe(new Observer<TextViewTextChangeEvent>() {
-
@Override
-
public void onCompleted() {
-
log.d("onComplete");
-
}
-
-
@Override
-
public void onError(Throwable e) {
-
log.d("Error");
-
}
-
-
@Override
-
public void onNext(TextViewTextChangeEvent onTextChangeEvent) {
-
log.d(format("Searching for %s", onTextChangeEvent.text().toString()));
-
}
-
});
三、Retrofit結合RxJava做網路請求框架
這裡不作詳解,具體的介紹可以看扔物線的這篇文章,對RxJava的入門者有很大的啟發。其中也講到了RxJava和Retrofit如何結合來實現更簡潔的程式碼
四、RxJava代替EventBus進行資料傳遞:RxBus
注意:RxBus並不是一個庫,而是一種模式,是使用了RxJava的思想來達到EventBus的資料傳遞效果。這篇文章把RxBus講的比較詳細。
五、使用combineLatest合併最近N個結點
例如:註冊的時候所有輸入資訊(郵箱、密碼、電話號碼等)合法才點亮註冊按鈕。
- Observable<CharSequence> _emailChangeObservable = RxTextView.textChanges(_email).skip(1);
- Observable<CharSequence> _passwordChangeObservable = RxTextView.textChanges(_password).skip(1);
- Observable<CharSequence> _numberChangeObservable = RxTextView.textChanges(_number).skip(1);
-
- Observable.combineLatest(_emailChangeObservable,
- _passwordChangeObservable,
- _numberChangeObservable,
- new Func3<CharSequence, CharSequence, CharSequence, Boolean>() {
- @Override
- public Boolean call(CharSequence newEmail,
- CharSequence newPassword,
- CharSequence newNumber) {
-
- Log.d("xiayong",newEmail+" "+newPassword+" "+newNumber);
- boolean emailValid = !isEmpty(newEmail) &&
- EMAIL_ADDRESS.matcher(newEmail).matches();
- if (!emailValid) {
- _email.setError("Invalid Email!");
- }
-
- boolean passValid = !isEmpty(newPassword) && newPassword.length() > 8;
- if (!passValid) {
- _password.setError("Invalid Password!");
- }
-
- boolean numValid = !isEmpty(newNumber);
- if (numValid) {
- int num = Integer.parseInt(newNumber.toString());
- numValid = num > 0 && num <= 100;
- }
- if (!numValid) {
- _number.setError("Invalid Number!");
- }
-
- return emailValid && passValid && numValid;
-
- }
- })//
- .subscribe(new Observer<Boolean>() {
- @Override
- public void onCompleted() {
- log.d("completed");
- }
-
- @Override
- public void onError(Throwable e) {
- log.d("Error");
- }
-
- @Override
- public void onNext(Boolean formValid) {
- _btnValidIndicator.setEnabled(formValid);
- }
- });
六、使用merge合併兩個資料來源。
例如一組資料來自網路,一組資料來自檔案,需要合併兩組資料一起展示。
- Observable.merge(getDataFromFile(), getDataFromNet())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(new Subscriber<String>() {
- @Override
- public void onCompleted() {
- log.d("done loading all data");
- }
-
- @Override
- public void onError(Throwable e) {
- log.d("error");
- }
-
- @Override
- public void onNext(String data) {
- log.d("all merged data will pass here one by one!")
- });
七、使用concat和first做快取
依次檢查memory、disk和network中是否存在資料,任何一步一旦發現資料後面的操作都不執行。
-
Observable<String> memory = Observable.create(new Observable.OnSubscribe<String>() {
-
@Override
-
public void call(Subscriber<? super String> subscriber) {
-
if (memoryCache != null) {
-
subscriber.onNext(memoryCache);
-
} else {
-
subscriber.onCompleted();
-
}
-
}
-
});
-
Observable<String> disk = Observable.create(new Observable.OnSubscribe<String>() {
-
@Override
-
public void call(Subscriber<? super String> subscriber) {
-
String cachePref = rxPreferences.getString("cache").get();
-
if (!TextUtils.isEmpty(cachePref)) {
-
subscriber.onNext(cachePref);
-
} else {
-
subscriber.onCompleted();
-
}
-
}
-
});
-
-
Observable<String> network = Observable.just("network");
-
-
//依次檢查memory、disk、network
-
Observable.concat(memory, disk, network)
-
.first()
-
.subscribeOn(Schedulers.newThread())
-
.subscribe(s -> {
-
memoryCache = "memory";
-
System.out.println("--------------subscribe: " + s);
-
});
八、使用timer做定時操作。當有“x秒後執行y操作”類似的需求的時候,想到使用timer
例如:2秒後輸出日誌“hello world”,然後結束。
-
Observable.timer(2, TimeUnit.SECONDS)
-
.subscribe(new Observer<Long>() {
-
@Override
-
public void onCompleted() {
-
log.d ("completed");
-
}
-
-
@Override
-
public void onError(Throwable e) {
-
log.e("error");
-
}
-
-
@Override
-
public void onNext(Long number) {
-
log.d ("hello world");
-
}
-
});
九、使用interval做週期性操作。當有“每隔xx秒後執行yy操作”類似的需求的時候,想到使用interval
例如:每隔2秒輸出日誌“helloworld”。
-
Observable.interval(2, TimeUnit.SECONDS)
-
.subscribe(new Observer<Long>() {
-
@Override
-
public void onCompleted() {
-
log.d ("completed");
-
}
-
-
@Override
-
public void onError(Throwable e) {
-
log.e("error");
-
}
-
-
@Override
-
public void onNext(Long number) {
-
log.d ("hello world");
-
}
-
});
十、使用throttleFirst防止按鈕重複點選
ps:debounce也能達到同樣的效果
-
RxView.clicks(button)
-
.throttleFirst(1, TimeUnit.SECONDS)
-
.subscribe(new Observer<Object>() {
-
@Override
-
public void onCompleted() {
-
log.d ("completed");
-
}
-
-
@Override
-
public void onError(Throwable e) {
-
log.e("error");
-
}
-
-
@Override
-
public void onNext(Object o) {
-
log.d("button clicked");
-
}
-
});
十一、使用schedulePeriodically做輪詢請求
-
Observable.create(new Observable.OnSubscribe<String>() {
-
@Override
-
public void call(final Subscriber<? super String> observer) {
-
-
Schedulers.newThread().createWorker()
-
.schedulePeriodically(new Action0() {
-
@Override
-
public void call() {
-
observer.onNext(doNetworkCallAndGetStringResult());
-
}
-
}, INITIAL_DELAY, POLLING_INTERVAL, TimeUnit.MILLISECONDS);
-
}
-
}).subscribe(new Action1<String>() {
-
@Override
-
public void call(String s) {
-
log.d("polling….”));
-
}
-
})
十二、RxJava進行陣列、list的遍歷
-
String[] names = {"Tom", "Lily", "Alisa", "Sheldon", "Bill"};
-
Observable
-
.from(names)
-
.subscribe(new Action1<String>() {
-
@Override
-
public void call(String name) {
-
log.d(name);
-
}
-
});
十三、解決巢狀回撥(callback hell)問題
-
NetworkService.getToken("username", "password")
-
.flatMap(s -> NetworkService.getMessage(s))
-
.subscribe(s -> {
-
System.out.println("message: " + s);
-
})
十四、響應式的介面
比如勾選了某個checkbox,自動更新對應的preference
-
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
-
RxSharedPreferences rxPreferences = RxSharedPreferences.create(preferences);
-
-
Preference<Boolean> checked = rxPreferences.getBoolean("checked", true);
-
-
CheckBox checkBox = (CheckBox) findViewById(R.id.cb_test);
-
RxCompoundButton.checkedChanges(checkBox)
-
.subscribe(checked.asAction());
最後,由於個人能力有限,文章難免有疏漏之處,如果您有任何疑議,請讓我知道,謝謝!本文所有的例子已經上傳到github上
致謝:這篇文章的絕大多數例子是從這裡總結的,還有部分例子來自這裡。對作者的無私貢獻表示感謝!