[英]unexpected behaviour of debounce() operator in RxJava
我正在使用RxBinding
來驗證表單輸入。
問題是當我嘗試按以下方式在應用程序行為不當時使用debounce()
運算符時,它不會崩潰,但僅在我打開調用setupForm()
的活動后,該應用程序重新啟動, 而沒有出現崩潰的跡象。
當我刪除debounce()
它可以正常工作。
這是我的代碼。
private void setupForm() {
Observable<Boolean> itemNameObservable = RxTextView.textChanges(tilItemName.getEditText()).
map(text -> (text.toString().length() > 6))
.distinctUntilChanged();
itemNameObservable.subscribe(valid -> {
tilItemName.setError(getString(R.string.error_invalid_itemNam));
tilItemName.setErrorEnabled(!valid);
});
Observable<Boolean> descObservable = RxTextView.textChanges(tilItemDescription.getEditText()).
map(text -> (text.toString().length() > 6))
.debounce(500, TimeUnit.MILLISECONDS)
.distinctUntilChanged();
descObservable.subscribe(valid -> {
tilItemDescription.setError(getString(R.string.error_invalid_description));
tilItemDescription.setErrorEnabled(!valid);
});
Observable<Boolean> cityObservable = RxTextView.textChanges(tilFinderCity.getEditText()).
map(text -> (text.toString().length() > 6))
.debounce(500, TimeUnit.MILLISECONDS)
.distinctUntilChanged();
cityObservable.subscribe(valid -> {
tilFinderCity.setError(getString(R.string.error_invalid_city));
tilFinderCity.setErrorEnabled(!valid);
});
Observable<Boolean> phoneObservable = RxTextView.textChanges(tilFinderPhone.getEditText()).
map(text -> (text.toString().length() > 6))
.debounce(500, TimeUnit.MILLISECONDS)
.distinctUntilChanged();
phoneObservable.subscribe(valid -> {
tilFinderPhone.setError(getString(R.string.error_invalid_phone));
tilFinderPhone.setErrorEnabled(!valid);
});
//combine all value from inputs and (&&) them. add button is enabled if all are set
Observable.combineLatest(
itemNameObservable
, descObservable
, cityObservable,
phoneObservable
, (itemNameIsValid, descIsValid, cityIsValid, phoneIsValid) -> (cityIsValid && descIsValid && phoneIsValid && itemNameIsValid))
.distinctUntilChanged()
.subscribe(shouldEnable -> btnAddItem.setEnabled(shouldEnable));
RxView.clicks(btnAddItem)
.subscribe(view -> presnter.addItem(getItemFromForm()));
}
默認情況下, debounce
運算符在computation
調度程序上運行,這就是您的應用程序崩潰的原因。 您可以通過查看日志來驗證是否會看到類似以下內容的android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
解決方案是在.observeOn(AndroidSchedulers.mainThread())
debounce()
調用之后立即添加.observeOn(AndroidSchedulers.mainThread())
這行。
使用RxTextView.textChanges時,請記住,在訂閱期間,它將立即發出結果,因此您必須考慮到這一點。 它要么不會影響您的代碼,要么您可以執行.skip(1)之類的操作
我認為在進行反跳操作時,您還應該包括反壓策略,因此請嘗試以下操作:
Observable<Boolean> phoneObservable =
RxTextView.textChanges(tilFinderPhone.getEditText())
.map(text -> (text.toString().length() > 6))
.debounce(500, TimeUnit.MILLISECONDS)
.toFlowable(BackpressureStrategy.LATEST)
.distinctUntilChanged();
這將:
/**
* Keeps only the latest onNext value, overwriting any previous value if the
* downstream can't keep up.
*/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.