Skip to content

Instantly share code, notes, and snippets.

@matpag
Created September 7, 2021 10:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matpag/8efce4239395749be314eb1d58525b5a to your computer and use it in GitHub Desktop.
Save matpag/8efce4239395749be314eb1d58525b5a to your computer and use it in GitHub Desktop.
LifecycleControlledCountDownTimer a wrapper class around CountDownTimer
import android.os.CountDownTimer
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.OnLifecycleEvent
import timber.log.Timber
interface LifecycleControlledCountDownTimer {
fun start(
onIntervalTick: (millisUntilFinished: Long) -> Unit,
onFinished: () -> Unit
)
fun cancel(callFinish: Boolean)
}
/**
* A [CountDownTimer] which stop itself if the lifecycle goes to [Lifecycle.State.PAUSE] state.
* If paused by Lifecycle [onFinished] will not be called automatically, you need to handle this case yourself
*
* Can be manually started using [start] and canceled with [cancel]
*/
private class LifecycleControlledCountDownTimerImpl constructor(
private val lifecycleOwner: LifecycleOwner,
private val durationMillis: Long,
private val intervalMillis: Long
): LifecycleControlledCountDownTimer, LifecycleObserver {
private var countDownTimer: CountDownTimer? = null
init {
lifecycleOwner.lifecycle.addObserver(this)
}
override fun start(
onIntervalTick: (millisUntilFinished: Long) -> Unit,
onFinished: () -> Unit
) {
if (lifecycleOwner.lifecycle.currentState == Lifecycle.State.DESTROYED) {
// ignore
Timber.i("lifecycle countdown: lifecycle-state is destroyed")
return
}
if (!lifecycleOwner.lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {
Timber.i("lifecycle countdown: lifecycle-state is not resumed yet")
return
}
//cancel already pending timer if present
cancel(false)
//create and start timer
countDownTimer = object : CountDownTimer(durationMillis, intervalMillis) {
override fun onTick(millisUntilFinished: Long) {
onIntervalTick(millisUntilFinished)
}
override fun onFinish() {
onFinished()
}
}.start()
}
override fun cancel(callFinish: Boolean) {
if (countDownTimer == null) return
Timber.i("lifecycle countdown: canceled, callFinish: $callFinish")
if (callFinish) {
countDownTimer!!.onFinish()
}
countDownTimer!!.cancel()
countDownTimer = null
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun pause() {
lifecycleOwner.lifecycle.removeObserver(this)
Timber.i("lifecycle countdown: stop called automatically")
cancel(false)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment