0

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()));


}
4

2 回答 2

4

debounce操作员默认在调度程序上运行,这computation就是您的应用程序崩溃的原因。您可以通过查看日志来验证,您会看到类似这样的内容android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

解决方案是在通话.observeOn(AndroidSchedulers.mainThread())后立即添加此行。debounce()

于 2018-07-07T03:41:13.473 回答
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.
 */
于 2018-03-23T04:41:29.913 回答