본문 바로가기
개발 이야기/안드로이드 개발

Android 에서 째깍째깍 타이머 구현하기

by 정선한 2024. 5. 3.
728x90
반응형

일단 기본적으로 Android에서는 타이머를 쉽게 사용할 수 있도록 클래스를 제공해주고 있습니다.

  • CountDownTimer : Android os 패키지 내에서 제공

따라서 간단하게 object를 상속받아서 사용할 수도 있지만 저는 조금 더 중복코드를 줄이기 위해서 추상화 클래스를 하나 생성하여 구현해보려고 합니다. 또한 CountDownTimer를 이용하여 일시정지까지 가능하도록 재구현을 해보려고 합니다.

추상화 클래스를 만들기 전에, object를 어떤 식으로 구현해서 사용하는기 기본적으로 알아보려고 합니다.


코드 화면 내에서 타이머가 필요한 경우, 활용할 수 있는 사용법 입니다.

저는 화면 코드 내에서 countDownTimer를 전역변수로 두고 object의 인스턴스를 선언해 주었습니다.

onTick() , onFinish()는 CountDownTimer에서 추상화 함수로 제공하는 내용으로
타이머의 Interval단위마다 불리는 onTick()과 종료 시 불려지는 onFinish()가 있습니다.

저는 1초 단위의 타이머가 필요했기에 INTERVAL은 1000으로 세팅하였습니다.

타이머 선언 및 실행 시,

countDownTimer = object : CountDownTimer(millisInFuture, COUNTDOWN_INTERVAL) {
    override fun onTick(millisUntilFinished: Long) {

        /**
         * 타이머 진행 시 수행 할 내용
        **/
    }

    override fun onFinish() {
        /**
         * 타이머 종료 시 수행 할 내용
        **/
    }
}

countDownTimer.start()

타이머 정지 시,

countDownTimer.cancel()

위의 방식으로 object를 생성하여 사용하는 경우, 여러 화면에서 사용할 때에는 동일한 로직을 여러 번 넣어야 하기 때문에 코드 유지보수 측면에서 공통적으로 묶어줄 수 있는 내용들을 분류하여 추상화 클래스를 구현하려고 합니다.


주요 기능,

  • 타이머 시작
  • 타이머 정지
  • 타이머 초기화

저는 이 3가지를 가장 큰 함수로 묶었고, 추상화 함수는 기존 CountDownTimer의 추상화 함수를 동일한 기능을 할 수 있도록 함수 명을 변경하여 선언해 주었습니다

  • onTimerTick()
  • onTimeFinish()

아래의 코드가 새롭게 추상화 클래스로 만들어진 CustomTimer 클래스 코드입니다.

import android.os.CountDownTimer

abstract class CustomTimer {

    abstract fun onTimerTick(millisUntilFinished: Long)
    abstract fun onTimerFinish()

    companion object {
        private const val COUNTDOWN_INTERVAL = 1000L
    }

    private lateinit var mCountDownTimer: CountDownTimer

    fun startTimer(timer: Long) {
        mCountDownTimer = object : CountDownTimer(
            timer,
            COUNTDOWN_INTERVAL
        ) {
            override fun onTick(millisUntilFinished: Long) {
                onTimerTick(millisUntilFinished)
            }

            override fun onFinish() {
                onTimerFinish()
            }
        }.start()
    }

    fun pauseTimer() {
        mCountDownTimer.cancel()
    }

    fun resetTimer(millisInFuture: Long) {
        pauseTimer()
        startTimer(millisInFuture)
    }
}

 

일단 기본적으로 CountDownTimer는 시작과 완료에 대한 내용만 확인할 수 있는데, 이를 일시정지 기능과 같이 사용할 수 있도록, onTick() 시점에, 남은 시간에 대한 변수를 하나 두고 다시 재생했을 때, 남은 시간을 대입하여 사용할 수 있도록 구상하였습니다.

찾아보니까 아예 타이머 코드를 새로 만드는 경우도 있던데, 
그렇게 하는 건 꽤나 번거로운 일이라 주어진 코드를 최대한 활용하는 방안으로 수정하였습니다.

위 추상화 클래스를 구현한 후, 필요한 지점에서 아래와 같이 대입하여 사용하였습니다. 타이머를 이용하고자 하는 화면 코드 내에서 생성한 추상화 클래스의 object를 생성하여, 추상화 함수 내에 수행할 내용을 작성하도록 하였습니다.

이때, onTimerTick() 함수 내에 남은 시간을 설정해 줍니다. 각 Interval에 맞게 남은 시간을 설정할 수 있습니다.

private var timeLeftInMillis: Long = 0L

private var mTimer = object : CustomTimer() {
    override fun onTimerTick(millisUntilFinished: Long) {
        timeLeftInMillis = millisUntilFinished

        /**
         * 타이머 진행 시 수행 할 내용
         **/
    }

    override fun onTimerFinish() {
        /**
         * 타이머 종료 시 수행 할 내용
         **/
    }
}

 

이렇게 객체 설정 후에는 mTimer 객체 변수를 사용하여 전역함수들을 사용할 수 있습니다.

mTimer.startTimer(세팅 시간 지정) --> 타이머 시작
mTimer.pauseTimer()            --> 타이머 정지
mTimer.resetTimer(세팅 시간 지정) --> 타이머 재시작

이렇게 이미 제공되는 클래스의 변형으로 간단하게 타이머를 변경해 보았습니다. 객체 변수에 대한 null type 같은 부분만 조심해 주면 큰 이슈는 없는 것 같기는 한데, 추가적으로 이슈가 발생하면 업데이트하러 돌아오겠습니다.

728x90
반응형