小编典典

/*

* Copyright (C) 2010 Andrew Gainer

*

* Licensed under the Apache License, Version 2.0 (the "License");

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

* http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*/

// Adapted from Android's CountDownTimer class

package com.cycleindex.multitimer;

import android.os.Handler;

import android.os.Message;

import android.os.SystemClock;

/**

* Schedule a countdown until a time in the future, with

* regular notifications on intervals along the way.

*

* The calls to {@link #onTick(long)} are synchronized to this object so that

* one call to {@link #onTick(long)} won't ever occur before the previous

* callback is complete. This is only relevant when the implementation of

* {@link #onTick(long)} takes an amount of time to execute that is significant

* compared to the countdown interval.

*/

public abstract class CountDownTimerWithPause {

/**

* Millis since boot when alarm should stop.

*/

private long mStopTimeInFuture;

/**

* Real time remaining until timer completes

*/

private long mMillisInFuture;

/**

* Total time on timer at start

*/

private final long mTotalCountdown;

/**

* The interval in millis that the user receives callbacks

*/

private final long mCountdownInterval;

/**

* The time remaining on the timer when it was paused, if it is currently paused; 0 otherwise.

*/

private long mPauseTimeRemaining;

/**

* True if timer was started running, false if not.

*/

private boolean mRunAtStart;

/**

* @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 in millis at which to execute

* {@link #onTick(millisUntilFinished)} callbacks

* @param runAtStart True if timer should start running, false if not

*/

public CountDownTimerWithPause(long millisOnTimer, long countDownInterval, boolean runAtStart) {

mMillisInFuture = millisOnTimer;

mTotalCountdown = mMillisInFuture;

mCountdownInterval = countDownInterval;

mRunAtStart = runAtStart;

}

/**

* Cancel the countdown and clears all remaining messages

*/

public final void cancel() {

mHandler.removeMessages(MSG);

}

/**

* Create the timer object.

*/

public synchronized final CountDownTimerWithPause create() {

if (mMillisInFuture <= 0) {

onFinish();

} else {

mPauseTimeRemaining = mMillisInFuture;

}

if (mRunAtStart) {

resume();

}

return this;

}

/**

* Pauses the counter.

*/

public void pause () {

if (isRunning()) {

mPauseTimeRemaining = timeLeft();

cancel();

}

}

/**

* Resumes the counter.

*/

public void resume () {

if (isPaused()) {

mMillisInFuture = mPauseTimeRemaining;

mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;

mHandler.sendMessage(mHandler.obtainMessage(MSG));

mPauseTimeRemaining = 0;

}

}

/**

* Tests whether the timer is paused.

* @return true if the timer is currently paused, false otherwise.

*/

public boolean isPaused () {

return (mPauseTimeRemaining > 0);

}

/**

* Tests whether the timer is running. (Performs logical negation on {@link #isPaused()})

* @return true if the timer is currently running, false otherwise.

*/

public boolean isRunning() {

return (! isPaused());

}

/**

* Returns the number of milliseconds remaining until the timer is finished

* @return number of milliseconds remaining until the timer is finished

*/

public long timeLeft() {

long millisUntilFinished;

if (isPaused()) {

millisUntilFinished = mPauseTimeRemaining;

} else {

millisUntilFinished = mStopTimeInFuture - SystemClock.elapsedRealtime();

if (millisUntilFinished < 0) millisUntilFinished = 0;

}

return millisUntilFinished;

}

/**

* Returns the number of milliseconds in total that the timer was set to run

* @return number of milliseconds timer was set to run

*/

public long totalCountdown() {

return mTotalCountdown;

}

/**

* Returns the number of milliseconds that have elapsed on the timer.

* @return the number of milliseconds that have elapsed on the timer.

*/

public long timePassed() {

return mTotalCountdown - timeLeft();

}

/**

* Returns true if the timer has been started, false otherwise.

* @return true if the timer has been started, false otherwise.

*/

public boolean hasBeenStarted() {

return (mPauseTimeRemaining <= mMillisInFuture);

}

/**

* Callback fired on regular interval

* @param millisUntilFinished The amount of time until finished

*/

public abstract void onTick(long millisUntilFinished);

/**

* Callback fired when the time is up.

*/

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 (CountDownTimerWithPause.this) {

long millisLeft = timeLeft();

if (millisLeft <= 0) {

cancel();

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 = mCountdownInterval - (SystemClock.elapsedRealtime() - lastTickStart);

// special case: user's onTick took more than mCountdownInterval to

// complete, skip to next interval

while (delay < 0) delay += mCountdownInterval;

sendMessageDelayed(obtainMessage(MSG), delay);

}

}

}

};

}

资料来源:本要点。

2020-09-18

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐