You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RxJava定时器点击按钮B二次启动无响应问题排查求助

问题原因与解决方案

嘿,这个问题我之前也碰到过!咱们一步一步拆解为啥第二次点击按钮没反应:

核心问题1:time变量没有重置

第一次定时器跑完后,time已经变成0了对吧?第二次点击按钮调用timerStart()时,刚进入accept方法就判断time > 0不成立,直接执行hideTimer()——所以看起来啥反应都没有,其实是它直接跳过了倒计时逻辑,立刻隐藏了TimerView。

核心问题2:重复订阅导致资源泄漏+逻辑混乱

每次点击按钮,你都会创建一个新的Observable.interval并添加到CompositeDisposable里,但旧的Observable并没有被停止!第一次的定时器在time到0之后,还是会每秒发射一次事件,每次都走else分支执行hideTimer()。而且多个订阅同时修改同一个time变量,逻辑只会越来越混乱。

修复方案:给你两个靠谱的实现方式

方案1:重置时间+自动终止Observable

用take()操作符让Observable在发射指定次数后自动完成,同时每次启动前重置time并清空旧订阅:

@Override
public void timerStart() {
    // 1. 重置倒计时时间为59秒
    time = 59;
    // 2. 清空之前的所有订阅,避免多个Observable同时运行
    getCompositeDisposable().clear();
    
    getCompositeDisposable()
        .add(Observable.interval(0, 1000, TimeUnit.MILLISECONDS)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            // 只发射60次(0到59秒,共60次),发射完自动完成
            .take(60)
            .subscribe(
                aLong -> {
                    String timer = String.format("%s:%s", "00", time <= 9 ? "0" + time : String.valueOf(time));
                    getMvpView().updateTimer(timer);
                    time--;
                },
                throwable -> getMvpView().hideTimer(),
                // Observable完成时触发,隐藏TimerView
                () -> getMvpView().hideTimer()
            )
        );
}

方案2:单独管理每个定时器(支持中途取消)

如果需要更精准的控制(比如中途可以手动取消倒计时),可以把当前的Disposable存起来,每次启动前先取消旧的:

private Disposable timerDisposable;

@Override
public void timerStart() {
    // 先取消旧的定时器
    if (timerDisposable != null && !timerDisposable.isDisposed()) {
        timerDisposable.dispose();
    }
    time = 59;
    
    timerDisposable = Observable.interval(0, 1000, TimeUnit.MILLISECONDS)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .take(60)
            .subscribe(
                aLong -> {
                    String timer = String.format("%s:%s", "00", time <= 9 ? "0" + time : String.valueOf(time));
                    getMvpView().updateTimer(timer);
                    time--;
                },
                throwable -> getMvpView().hideTimer(),
                () -> getMvpView().hideTimer()
            );
    
    getCompositeDisposable().add(timerDisposable);
}

这样修改后,不管你点多少次按钮B,每次都会先清理旧的定时器、重置时间,然后启动新的倒计时流程,就不会出现没反应的情况啦!

内容的提问来源于stack exchange,提问作者Abhishek Tiwari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:07:13