簡體   English   中英

RxJava中的debounce()運算符的意外行為

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM