我正在使用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()));
}
答案 0 :(得分:1)
debounce
运算符默认在computation
调度程序上运行,这就是您的应用程序崩溃的原因。
您可以通过查看日志来验证,您会看到类似android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
解决方案是在.observeOn(AndroidSchedulers.mainThread())
调用之后立即添加此行debounce()
。
答案 1 :(得分:0)
使用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.
*/