android - 使用 Rx 去抖按钮点击

标签 android rx-java rx-android

我正在尝试制作一个简单的“按钮去抖动器”,它将计算过滤后的点击次数并通过 TextView 显示它。我想以忽略间隔时间小于 300 毫秒的点击的方式过滤快速/垃圾点击。

我做了我的研究并偶然发现了 Rx 的很棒的 debounce() 理论上它应该做我想要的事情..

..我是这么想的。由于该应用程序似乎只记录了第一次点击;无论我试图等待多久,计数器都不会增加。

这是我的一段代码:

    ...

    RxView.clicks(mButton)
        .debounce(300, TimeUnit.MILLISECONDS)
        .subscribe(new Subscriber<Object>() {
            public int mCount;

            @Override
            public void onCompleted() {
            }

            @Override
            public void onError(Throwable e) {
            }

            @Override
            public void onNext(Object o) {
                mText.setText(String.valueOf(++mCount));
            }
        });

    ...

我做错了什么?我试过在没有 debounce() 的情况下运行这个东西,它工作得很好(每次点击按钮时计数器都会增加)。

提前致谢!

最佳答案

请注意 documentation on the debounce operator 中的以下内容:

This variant operates by default on the computation Scheduler (...)

或者,在代码方面,这当前发生了:

public final Observable<T> debounce(long timeout, TimeUnit unit) {
    return debounce(timeout, unit, Schedulers.computation());
}

因此,订阅者的回调将在同一个计算调度程序上调用,因为没有其他内容明确指示。

现在,尝试从主/ui 线程以外的任何其他线程更新 View (这就是 onNext() 中发生的事情)是错误的,它会导致不确定的结果。

幸运的是,上面引用的其余部分也提供了解决方案:

(...) but you can optionally pass in a Scheduler of your choosing as a third parameter.

这会导致:

RxView.clicks(mButton)
    .debounce(300, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
    .subscribe(...);

或者,您仍然可以让去抖动发生在计算调度程序上,但在主/ui 线程上接收通知:

RxView.clicks(mButton)
    .debounce(300, TimeUnit.MILLISECONDS)
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(...);

无论哪种方式都将确保在主/ui 线程上收到通知,从而从正确的线程更新 View 。

关于android - 使用 Rx 去抖按钮点击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32498210/

相关文章:

android - 删除/system/xbin/su 会阻止 root 访问吗?

xml - 使用 Android 生成的 ant 构建文件时如何为 JAR 指定 lib 文件夹?

java - RxJava : Connect observers?

android - RxAndroid - 点击重试观察

android - 用于改造响应代码处理的自定义 rx Func1

java - RoboGuice 的 RoboActionBarActivity

java - Android 获取上周日期

android - 基于 BroadcastReceiver 获取 wifi SSID 列表并返回 Rx.Observable 的服务进行单元测试

android - 当 Observable 在 Schedulers.io() 上订阅时从不正确的线程访问 Realm

android - RxJava,平面图的好用例