安卓java 倒计时_用RxJava实现倒计时与踩坑

本文介绍了如何使用RxJava在Android上实现倒计时功能,通过`interval()`和`map()`操作符转换计数为倒计时。然而,在实际运行中发现5秒倒计时存在错误,5和4会同时执行。经过排查,发现将`.subscribeOn(AndroidSchedulers.mainThread())`删除后问题解决,原来是因为指定主线程导致的计时不准。最后,作者更新说明问题源于自己的编译环境而非RxJava本身。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

废话不多说直接上代码:

public class RxCountDown {

public static Observable countdown(int time) {

if (time < 0) time = 0;

final int countTime = time;

return Observable.interval(0, 1, TimeUnit.SECONDS)

.subscribeOn(AndroidSchedulers.mainThread())

.observeOn(AndroidSchedulers.mainThread())

.map(new Func1() {

@Override

public Integer call(Long increaseTime) {

return countTime - increaseTime.intValue();

}

})

.take(countTime + 1);

}

}

代码比较简单,利用 interval() 定时发送 Observable ,通过 map() 将 0、1、2、3... 的计数变为 ...3、2、1、0 倒计时。通过 take() 取 >=0 的 Observable 。

使用时:

RxCountDown.countdown(5)

.doOnSubscribe(new Action0() {

@Override

public void call() {

appendLog("开始计时");

}

})

.subscribe(new Subscriber() {

@Override

public void onCompleted() {

appendLog("计时完成");

}

@Override

public void onError(Throwable e) {

}

@Override

public void onNext(Integer integer) {

appendLog("当前计时:" + integer);

}

});

这样就实现了一个5秒的倒计时。

运行结果:

D/HIDETAG:

D/HIDETAG:

D/HIDETAG:

D/HIDETAG:

D/HIDETAG:

D/HIDETAG:

D/HIDETAG:

D/HIDETAG:

WTF…… 5 与 4 怎么同时执行了!反倒是 doOnSubscribe() 与 计时5 之间有1秒的间隔,很明显有BUG。

这么几行代码找了1个小时没找到问题在哪里……后来尝试着把 .subscribeOn(AndroidSchedulers.mainThread()) 删除,然后又运行了一下:

D/HIDETAG:

D/HIDETAG:

D/HIDETAG:

D/HIDETAG:

D/HIDETAG:

D/HIDETAG:

D/HIDETAG:

D/HIDETAG:

居然正确了,倒计时正常工作了……

不知道是 Rx 的BUG还是我漏掉了什么知识, 为什么指定 subscribe 的线程为主线程会导致第一次计时不准确?

希望有知道的不吝赐教。

2016.2.16更新:找到原因了,不是Rx的锅,是我自己编译环境的问题……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值