为什么倒数计时器不能在不是活动的独立类上工作?

时间:2016-05-15 08:35:38

标签: java android countdowntimer

我正在尝试在Android中使用countdowntimer,以下是一个了解其行为的小测试代码

    new CountDownTimer(30000, 1000) {

        public void onTick(long millisUntilFinished) {
            System.out.println("tick");
        }

        public void onFinish() {
            System.out.println("finish");
        }
    }.start();

    System.out.println("done");

如果我将此代码段放在项目的MainActivity中,它运行正常,但不是在独立类中。为什么?

此外,倒数计时器是在主线程本身上运行,还是会产生另一个线程?

1 个答案:

答案 0 :(得分:1)

您的代码包含两部分:

    CountDownTimer cdt = new CountDownTimer(30000, 1000) {

    public void onTick(long millisUntilFinished) {
        System.out.println("tick");
    }

    public void onFinish() {
        System.out.println("finish");
    }
};

第一部分是实例化一个CountDownTimer对象,你可以把这个代码放在任何线程的任何地方,因为只创建了对象,它什么也没做。

第二部分是:

cdt.start();

您应该注意到CountDownTimer必须从主线程开始(从活动的onCreate或onResume ...调用它)。因此,如果将代码放在另一个类中,则不是问题,您必须确保在主线程上调用start()函数。

//更新:

你知道,CountDownTimer的onTick和onFinish函数总是在主线程上调用。 CountDownTimer不会运行任何线程。

它的代码是:

public synchronized final CountDownTimer start() {
    mCancelled = false;
    if (mMillisInFuture <= 0) {
        onFinish();
        return this;
    }
    mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;
    mHandler.sendMessage(mHandler.obtainMessage(MSG));
    return this;
}

很简单,CountDownTimer将由Handler发送消息。

这是Handler:

// handles counting down
private Handler mHandler = new Handler() {

    @Override
    public void handleMessage(Message msg) {

        synchronized (CountDownTimer.this) {
            if (mCancelled) {
                return;
            }

            final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();

            if (millisLeft <= 0) {
                onFinish();
            } else if (millisLeft < mCountdownInterval) {
                // no tick, just delay until done
                sendMessageDelayed(obtainMessage(MSG), millisLeft);
            } else {
                long lastTickStart = SystemClock.elapsedRealtime();
                onTick(millisLeft);

                // take into account user's onTick taking time to execute
                long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();

                // special case: user's onTick took more than interval to
                // complete, skip to next interval
                while (delay < 0) delay += mCountdownInterval;

                sendMessageDelayed(obtainMessage(MSG), delay);
            }
        }
    }
};

处理程序将发送一条延迟消息,用于调用下一个onTick()或onFinish()。所以它必须使用主线程(或主循环)。如果您希望它在自定义线程中运行,请按照您的方式重新实现:D