본문 바로가기

ANDROID/Debug Logs

[안드로이드] CountDownTimer의 시간 Sync 문제 해결하기

프로젝트에서 MediaPlayer와 CountDownTimer를 사용하면서 몇가지의 애로사항이 있었는데,

 

이를테면 영상을 중지하고 다시 재개할 때의 기존의 타이머를 어떻게 다시 설정하냐는 것이었다.

 

왜냐하면 CountDownTimer에는 별도의 pause 기능이 없고, stop만이 가능했기 때문이다.

 

원래부터 그랬다고 한다.

 

우선 기존의 요구사항은 아래와 같다.

 

  • MediaPlayer는 10개의 영상을 연달아 재생한다.
  • 각 영상은 각기 다른 재생시간을 가진다.
  • 영상은 10초의 대기시간을 가진 뒤 재생을 시작한다.
  • 사용자는 대기시간 및 재생중에도 상관없이 일시정지 및 다시시작(resume)이 가능하다.
  • 일시정지 및 다시시작, 재생을 진행하는데 모든 타임라인이 일치하여야 한다. (남은 시간, 경과 시간 등)

 

여기서 포인트는 일시정지 및 resume을 하는 부분에서

 

CountDownTimer가 일시정지가 안되는 것 때문에 손이 상당부분 가게 된 것이었는데,

 

시행착오 끝에 아래와 같은 솔루션으로 이를 해결할 수 있었다.

 


1. CountDownTimer를 init하는 별도의 function을 만든다.

private var exampleTimer: CountDownTimer? = null
private var latestRemainingTime: Long

fun setupTimer(millisInFuture: Long) {

	exampleTimer = object : CountDownTimer(millisInFuture, 1000) {
    	override fun onFinish() {
        	// 종료 이후 다음 영상을 재생
        }
        
        override fun onTick(millisUntilFinished: Long) {
        
        	// 남은 시간만큼을 경과시간에 적용한다. 
            // 이는 exampleTimer가 시작될 때 시점에 관계없이 onTick이 한번 호출되기 때문에
     		// 중복하여 시간이 집계되는 현상을 막기 위함.
        	mPresenter.countElapsedTime(latestRemainingTime - millisUntilFinished)
            
            // 마지막으로 onTick으로 들어온 남은 시간을 저장
            latestRemainingTime = millisUntilFinished
        }
   }
}

여기서 Presenter는 파라미터로 넘겨준 타이머의 남은 시간을 저장하고 있다가, 영상을 재개할 때 남은 시간을 타이머 재생성에 넘겨주는 역할을 함.

 

2. 사용자가 특정 동작에 Timer를 종료

 

3. 사용자가 다시 영상을 재개하면 마지막에 남아있던 남은 시간을 기반으로 Timer를 다시 init 후 시작.

...

fun whenResume() {
	setupTimer(mPresenter.getRemainingTime())
    exampleTimer.start()
}

...