用RxJava实现倒计时与踩坑

(转载)http://www.jianshu.com/p/17af7790e8a6

废话不多说直接上代码:

public class RxCountDown {

    public static Observable<Integer> 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<Long, Integer>() {
                    @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()>=0Observable

使用时:

RxCountDown.countdown(5)
           .doOnSubscribe(new Action0() {
                    @Override
                    public void call() {
                        appendLog("开始计时");
                    }
                })
           .subscribe(new Subscriber<Integer>() {
                    @Override
                    public void onCompleted() {
                        appendLog("计时完成");
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(Integer integer) {
                        appendLog("当前计时:" + integer);
                    }
                });

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

运行结果:

D/HIDETAG: <--  当前时间:0758628 --- 开始计时  -->
D/HIDETAG: <--  当前时间:0759646 --- 当前计时:5  -->
D/HIDETAG: <--  当前时间:0759647 --- 当前计时:4  -->
D/HIDETAG: <--  当前时间:0800646 --- 当前计时:3  -->
D/HIDETAG: <--  当前时间:0801646 --- 当前计时:2  -->
D/HIDETAG: <--  当前时间:0802645 --- 当前计时:1  -->
D/HIDETAG: <--  当前时间:0803646 --- 当前计时:0  -->
D/HIDETAG: <--  当前时间:0803650 --- 计时完成  -->

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

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

D/HIDETAG: <--  当前时间:1458142 --- 开始计时  -->
D/HIDETAG: <--  当前时间:1458162 --- 当前计时:5  -->
D/HIDETAG: <--  当前时间:1459163 --- 当前计时:4  -->
D/HIDETAG: <--  当前时间:1500150 --- 当前计时:3  -->
D/HIDETAG: <--  当前时间:1501150 --- 当前计时:2  -->
D/HIDETAG: <--  当前时间:1502149 --- 当前计时:1  -->
D/HIDETAG: <--  当前时间:1503150 --- 当前计时:0  -->
D/HIDETAG: <--  当前时间:1503151 --- 计时完成  -->

居然正确了,倒计时正常工作了……
不知道是Rx的BUG还是我漏掉了什么知识,为什么指定subscribe的线程为主线程会导致第一次计时不准确?
希望有知道的不吝赐教。


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



文/Hideeee(简书作者)
原文链接:http://www.jianshu.com/p/17af7790e8a6
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值