https://developer.android.com/reference/kotlin/android/os/Handler?_gl=1*11cwltx*_up*MQ..*_ga*OTI1ODMzOTE5LjE3MTY2MTE1MDY.*_ga_6HH9YJMN9M*MTcxNjYxMTUwNS4xLjAuMTcxNjYxMTUwNS4wLjAuMA..

 

Handler  |  Android Developers

 

developer.android.com

현재는 기본 api로 변경된 Splash를 만들던 때, " 3초 뒤에 MainActivity로 이동할게요 ! "

 

하는 과정에서 '3초 지연' 뭐 이런 구글링으로 찾아서 대부분 아는 Handler(Looper.geMainLooper()).postDelayed({}, [시간]) 이다.

 

아 그냥 이 코드를 사용하면 지연이 되는 구나! 해서 

 

내가 원하는 기능을 구현하려고 했다. 

 

 

내가 원하는 기능 

6번 루프를 돌면서 1번 루프가 실행되면 8초 동안 멈췄다가 다음 루프가 실행 되기. 

 

그냥 Handler로 구현해서 Log를 찍어봤더니 엥? 

 

private var repeatCount = 0

Log.v(TAG, "repeatCount: $repeatCount")
...
repeatCount++
...

이 repeatCount가 8초에 한번씩 올라가야 하는데? 전혀;

 

걍 0 1 2 3 4 5 6 하고 1초도 안걸려서 끝나버림.

알고보니 

이 Handler(Looper.getMainLooper()).postDelayed 는 비동기 방식이었던 것임...👊

 

아무튼 그래서 이 친구의 동작을 감지해서 연이어서 실행되지 않고 "특정 조건에서 다시 반복"해서 실행될 수 있게 하려고 찾아보니 

Runnable을 사용하라는 것.. 

 

아무튼 

Handler(Looper.getMainLooper()).postDelayed(object: Runnable {
    override fun run() {
    ...
    }
}, 5000) // 5초

이렇게 

postDelayed안에 Runnable Object를 추가하고 run() 안에 내가 지연시키고 시작시키고 싶은 동작 or 지연하고 반복하고 싶은 동작을 넣음 
 
그러면 어떻게 한 번 동작을 실행하고 멈춘다음 실행하는지는
private val delay = if (isRecording) 100000L else 65000L // 10초 or 6.5초


// 이 코드 
Handler(Looper.getMainLooper()).postDelayed(this, delay)

 

를 추가해서 시작함다

 

전체코드 

Handler(Looper.getMainLooper()).postDelayed(object: Runnable {
    override fun run() {
        if (repeatCount == 6) {
            mCountDown.cancel()
            detectbody.removeObserver(detectObserver)
            Log.v("repeat", "Max repeats reached. stop the loop")
            return
        }
        when (repeatCount) {
            1 -> {
                isCapture = false
                isRecording = true
            }
            else -> {
                isCapture = true
                isRecording = false
            }
        }
        Log.v("repeatCount", "$repeatCount")
        mCountDown.start()
        if (repeatCount <= maxRepeats) {
            Handler(Looper.getMainLooper()).postDelayed(this, 80000L)
        }

    }
}, 5000)

 

결과적으로 run() 안 코드는 실행이 계속해서 될 수 있음(이론상) -> return 으로 빠져나오지 않으면 계속 실행이 됨. 

 

코드 분석 

 

Handler(Looper.getMainLooper()).postDelayed(object: Runnable {
    override fun run() {
    
    ...
        
        if (repeatCount <= maxRepeats) {
            Handler(Looper.getMainLooper()).postDelayed(this, 80000L)
        }
    }
}, 5000)

// 외부에서 repeatCount++

여기서는 repeatCount가 6이 되지 않을 동안 계속해서 이 루프를 실행합니다. 대신? 8초를 기다렸다가요 ! 

 

가장 밖의 5000은 이 Runnable이 실행을 지연시키는 시간입니당 ㅎㅎ 

 

아무튼 그리고 무한루프에서 빠져나온다? 그러면 

Handler(Looper.getMainLooper()).postDelayed(object: Runnable {
    override fun run() {
        if (repeatCount == 6) {
            
           ...
            Log.v("repeat", "Max repeats reached. stop the loop")
            return
        }
...(후략)

 

여기서 repeatCount가 6이 도달했을 때 이 Loop가 완전히 멈추도록 합니다 return 으로요 ! 

 

이렇게 Runnable을 통해 비동기적으로 작동하는 postdelayed를 control해서 원하는 기능을 구현할 수 있었답니다..

 

ㅅㄱ

안드로이드 runnable 썸네일