Android倒计时工具CountDownTimer的用法及原理(一)

CountDownTimer是Android官方SDK提供的一个倒计时工具,其仍然是基于Handler send/post delay,可视作在倒计时这个特定的使用场景下对于Handler的一种封装。

用法

CountDownTimer使用起来是很方便的。CountDownTimer是一个抽象类,通过构造方法创建实例,并且实现两个抽象方法即可。start()方法为启动倒计时。

CountDownTimer countDownTimer = new CountDownTimer(1000L * 30, 1000L) {
            @Override
            public void onTick(long millisUntilFinished) {
                // your logic for tick
            }

            @Override
            public void onFinish() {
                // your logic for finish
            }
        };
        countDownTimer.start();

构造方法的两个参数均以毫秒为单位,第一个是倒计时总时长,第二个是收到tick回调的时间周期。上述例子中即倒计时30s,每1s一次tick。构造方法的两个参数说明:

    /**
     * @param millisInFuture The number of millis in the future from the call
     *   to {@link #start()} until the countdown is done and {@link #onFinish()}
     *   is called.
     * @param countDownInterval The interval along the way to receive
     *   {@link #onTick(long)} callbacks.
     */

主线程中使用

值得注意的是,CountDownTimer可以在主线程中直接使用。验证一下回调的执行线程。在主线程中执行如下代码:

CountDownTimer countDownTimer = new CountDownTimer(1000L * 30, 1000L) {
            @Override
            public void onTick(long millisUntilFinished) {
                // your logic for tick
                Log.i("TEST", "onTick - " + Thread.currentThread() + ", id - " + Thread.currentThread().getId());
            }

            @Override
            public void onFinish() {
                // your logic for finish

                Log.i("TEST", "onFinish" + Thread.currentThread() + ", id - " + Thread.currentThread().getId());
            }
        };
        countDownTimer.start();

Log:

02-24 14:05:13.545 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:14.546 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:15.548 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:16.550 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:17.551 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:18.553 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:19.555 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:20.557 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:21.560 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:22.563 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:23.566 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:24.569 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:25.571 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:26.573 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:27.575 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:28.578 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:29.580 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:30.581 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:31.583 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:32.586 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:33.588 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:34.589 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:35.592 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:36.595 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:37.598 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:38.599 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:39.601 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:40.602 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:41.604 30358 30358 I TEST    : onTick - Thread[main,5,main], id - 1
02-24 14:05:43.546 30358 30358 I TEST    : onFinishThread[main,5,main], id - 1

可见,回调执行在主线程,这也就意味着可以在回调中直接处理UI,还是很方便的。

在工作线程中使用

不能在工作线程中像主线程一样简单使用的原因,是CountDownTimer是基于Handler的,细节将在原理部分说明。主线程已经由安卓框架层启动了消息循环,所以可以直接使用。那么在工作线程中怎样使用呢?可以借助于HanderThread。在onLooperPrepared()中初始化并开启CountDownTimer:

        new HandlerThread("TestThread") {
            protected void onLooperPrepared() {
                CountDownTimer countDownTimer = new CountDownTimer(1000L * 30, 1000L) {
                    @Override
                    public void onTick(long millisUntilFinished) {
                        // your logic for tick
                        Log.i("TEST", "onTick - " + Thread.currentThread() + ", id - " + Thread.currentThread().getId());
                    }

                    @Override
                    public void onFinish() {
                        // your logic for finish
                        Log.i("TEST", "onFinish" + Thread.currentThread() + ", id - " + Thread.currentThread().getId());
                    }
                };
                countDownTimer.start();
            }
        }.start();

执行log如下:

02-24 14:03:35.789 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:03:36.790 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:03:37.793 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:03:38.795 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:03:39.797 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:03:40.800 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:03:41.801 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:03:42.803 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:03:43.804 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:03:44.806 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:03:45.809 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:03:46.810 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:03:47.813 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:03:48.814 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:03:49.816 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:03:50.818 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:03:51.820 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:03:52.821 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:03:53.823 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:03:54.825 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:03:55.827 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:03:56.828 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:03:57.829 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:03:58.831 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:03:59.832 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:04:00.835 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:04:01.836 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:04:02.838 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:04:03.840 30099 30222 I TEST    : onTick - Thread[TestThread,5,main], id - 473
02-24 14:04:05.791 30099 30222 I TEST    : onFinishThread[TestThread,5,main], id - 473

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值