为什么在Android的CountDownTimer内部需要同步方法和处理程序块?

时间:2019-05-29 15:23:15

标签: java android

如CountDownTimer类的Android开发人员文档中所述

“对onTick(long)的调用已同步到此对象,因此在上一次回调完成之前永远不会发生对onTick(long)的调用。这仅在onTick(long)的实现需要与倒计时间隔相比,执行时间是很重要的。“

但是在完成上一个onTick()回调之前不会调用onTick(long),因为只有在执行完当前handleMessage()方法之后,才会从messageQueue中提取下一条消息。

所有这些都是因为handleMessage()方法在主UI线程上运行,并且循环程序将提取仅对主UI线程执行的消息。 因此,循环程序将在当前消息完成后提取一条消息。

Android文档的链接-https://developer.android.com/reference/android/os/CountDownTimer

CountDownTimer类的实现代码在这里。

public abstract class CountDownTimer {

private final long mMillisInFuture;

private final long mCountdownInterval;

private long mStopTimeInFuture;

private boolean mCancelled = false;

public CountDownTimer(long millisInFuture, long countDownInterval) {
    mMillisInFuture = millisInFuture;
    mCountdownInterval = countDownInterval;
}

public synchronized final void cancel() {
    mCancelled = true;
    mHandler.removeMessages(MSG);
}

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

public abstract void onTick(long millisUntilFinished);

public abstract void onFinish();

private static final int MSG = 1;

// 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 {
                long lastTickStart = SystemClock.elapsedRealtime();
                onTick(millisLeft);

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

                if (millisLeft < mCountdownInterval) {
                    // just delay until done
                    delay = millisLeft - lastTickDuration;

                    // special case: user's onTick took more than interval to
                    // complete, trigger onFinish without delay
                    if (delay < 0) delay = 0;
                } else {
                    delay = mCountdownInterval - lastTickDuration;

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

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

我尝试过的是,我将所有代码复制到MyCountDownTimer类(我自己修改的CountDownTimer类)并删除了同步(通过删除标识符“ synchronized”),并使用MyCountDownTimer在onTick()中执行任务,这需要更多时间时间比countDown间隔时间短。但是我从常规实现和使用MyCountDownTimer的实现中都获得了相同的结果。

对于结果,我已经注销了一些信息。就像onTick()被调用的时间和次数。

所以我的问题是,为什么完全需要这种同步? Android Doc的内容正确吗?

0 个答案:

没有答案