앱 만들기/안드로이드

안드로이드의 기술 # Handler 타이머 구현하기

나도 처음이야 2020. 9. 2.

안드로이드 핸들러를 사용해서 타이머를 구현해보겠습니다.

총 2 개의 포스팅으로 나누어서 1강에서는 기본 타이머를 구현해보고,

2강에서는 타이머를 스탑 하는 기능을 만들어 보겠습니다.

다 만들면 하기처럼 됩니다.

 

 

 

그럼 지금 1강을 만들어 볼까요? :)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
// 스타트, 일시정지 버튼을 만듭니다.
        button = (Button)findViewById(R.id.button);
// 동작되는 타이머를 표시할 텍스트 뷰 입니다.
        textView = (TextView)findViewById(R.id.textView);

// 핸들러 객체를 만들어줍니다.
        timer = new TimerHandler();
 
    }
 
cs

 

우선, 위와 같이 UI 구성을 해줍니다.

버튼 하나와 텍스트 뷰 하나로 타이머의 기본 동작에 필요한 UI를 구성해 봅니다.

그리고, 가장 중요한 핸들러 객체를 만들어 봅니다.

 

여기서 잠깐, 핸들러의 기본 개념은 이러합니다.

핸들러 란, 안드로이드 OS에게 메시지를 던질 수 있는 객체로 스레드 간에 메시지를 주고받는 기능을  가능하게 만들어 줍니다.  UI 업데이트는 메인 스레드에서 하지만, 반복적이거나 무한 루프 구문을 메인 스레드에서 작업을 하게 되면

화면이 먹통이 됩니다. 

그렇기에 이런 작업들을 할 때는 별도의 스레드를 만들어서 작업하고, 핸들러를 통해서 메인 스레드에게 "너 쉴 때 

작업 좀 해줘" 하고 메시지를 보내야 합니다. 바로 이럴 때 핸들러를 사용하곤 합니다.

어쨌든 기본 개념 위와 같습니다

 

그럼, 타이머 구현을 위한 핸들러 객체를 정의해봅시다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 // 타이머 핸들러 클래스.
    class TimerHandler extends Handler{
 
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
 
            switch (msg.what){
                case 0// 시작 하기
                        if (timerTime == 0) {
                            textView.setText("Timer : " + timerTime);
                            removeMessages(0);
                            break;
                        }
                        // Main Thread 가 쉴때 Main Thread 가 실행하기에
                        // 오래걸리는 작업은 하면 안된다. (무한 루프 문 etc.. 은 쓰레드로)
                        textView.setText("Timer : " + timerTime--);
                        sendEmptyMessageDelayed(01000);
                        //Log.d("test", "msg.what:0 time = " + timerTime);
 
                    break;
                case 1//일시 정지
                    removeMessages(0); // 타이머 메시지 삭제
                    textView.setText("Timer : " + timerTime); // 현재 시간을 표시.
                    //Log.d("test" , "msg.what:1 time = " + timerTime);
                    break;
 
            }
 
        }
    }
cs

handleMessage()란 함수를 오버 라이딩해줍니다.

해당 함수는 메시지를 처리해주는 함수로써

msg.what의 번호에 따라서 우리가 하고자 하는 일들을 구별할 수 있답니다.

 

위 코드에서는 0번 일 때는 타이머를 동작시키기는 코드를 구현하겠습니다.

즉, 메시지 0번은 타이머 구동 코드입니다. 

sendEmptyMessageDelayed(01000);라는 함수를 통해서 1초 후에 OS에게 메시지를 보냅니다.

그러면 1초 후에 다시 handleMessage() 함수의 msg.what 0 부분이 실행되는 구조입니다.

이렇게 재귀 호출되면서, textView를 업데이트해주면 바로 타이머가 되는 것이죠.

 

그럼, case 1번은 바로 일시정지 기능입니다.

일시정지에서는 메시지 큐에 쌓여있던 메시지 0번을 삭제해줍니다.

 

removeMessage(0)

 

이렇게 하면 1초 전에 쏴주었던 메시지가 삭제되면서 반복 실행을 막아줍니다.

그리고, 현재 시간을 textView에 그려주면 바로 정지된 타이머의 모습이 됩니다.

 

case 0번에서도

removeMessage(0)가 사용되었죠. 바로 시간이 0 초가 되었다면

더 이상 반복이 필요치 않기 때문에 0번 메시지를 삭제하라는 의미입니다.

즉, 타이머가 중지하게 되죠.

 

++

 

그럼 해당 동작을 받는 버튼 함수를 구현해 볼까요?

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 public void onStartPauseButton(View view){
        // 타이머 시작!
        if(status == 0// 정지 상태 라면, 재 시작.
        {
            status = 1;
            timer.sendEmptyMessage(0);
            button.setText("일시정지");
 
        }else if(status == 1){ // 타이머 동작 중이라면, 일시 정지 시키기
 
            status = 0;
            // 1번 메시지를 던진다.
            timer.sendEmptyMessage(1);
            button.setText("시작");
        }
    }
cs

 

위와 같이 버튼 상태 값에 따라

sendEmptyMessage() 함수를 실행하고 있습니다.

해당 함수의 인자 값에 따라서, handleMessage()의 msg.what 구문이 실행됩니다.

 

이렇게 하면, 처음 구현 영상의 시작 및 일시정지 구현이 완료됩니다.

마지막으로 앱을 종료 시에도 메시지를 삭제해주어야겠죠?

현 상태에서는 타이머가 동작 중에 앱을 종료하더라도 계속해서 타이머가 동작을 합니다.

메시지가 살아 있기 때문이죠.

하기처럼 onDestory() 함수에서 앱 종료 시 메시지를 삭제하는 코드를 구현합니다.

 

1
2
3
4
5
6
   @Override
    protected void onDestroy() {
        super.onDestroy();
        if(timer != null)
            timer.removeMessages(0);
    }
cs

 

오늘은 핸들러 특징을 활용한 타이머를 구현해보았습니다.

해당 코드는 필자가 연습용으로 만든 코드이기에 자신에 맞게 구현을 하시면 더 좋을 거 같습니다.

타이머를 이용하면 여러 가지 기능 구현이 가능합니다.

게임 및 여러 가지 기능 등에서 타이머는 필수로 사용하게 됩니다.

 

다음 포스팅에서는 타이머 초기화(정지) 버튼을 만들어보겠습니다.

오늘도 즐거운 하루 보내세요.

감사합니다 :) 

반응형

댓글