안드로이드/정리(Android)

(Android) Handler란 무엇일까?

김염인 2022. 1. 13. 17:42

안드로이드 개발을 하다보면 Main Thread에서 UI작업을 해야 한다는 것은 알고 있을 것이다. 그렇다면 왜?? 굳이 Main Thread에서 UI를 작업해야 하나 생각하고 찾아보았다.

위와 같이 Main Thread와 Worker Thread에서 textview의 setText에 접근 한다고 해야한다, textView는 여기서 어느 Thread의 값을 적용시켜야 하는지 혼란에 빠지게 된다. 그래서 해결할 수 있도록 생각된 방법이 handler이다.

 



worker Thread는 hander를 통해 main Thread로 sendMessage를 통해 전달을 해준다. 그리고 수신을 받은 Main Thread에서 유연하게 작업을 해주는 것이다.

 

가끔씩 앱을 구현하다 보면은 1초 씩 딜레이를 시켜야 하는 상황이 있을 수 있다.

예를들면 타이머를 구현한다든가 아니면 시간초를 1초씩 경과해서 이벤트를 처리해야 한다던가

이럴때 유용한 것은 바로 Handler이다.

 

    private val countUpAction: Runnable = object: Runnable{
        override fun run() {
            val currentTimeStamp = SystemClock.elapsedRealtime()
            // 부팅된 시점부터 현재까지의 시간을 millisecond로 리턴합니다. 즉, 부팅 직후에는 0을 리턴하고 10초가 지났다면 10000이 리턴됩니다.
            //  중요한 것은 디바이스가 Sleep 상태에 있어도 시간은 측정이 됩니다. 만약 부팅된지 10초가 지났고, 이 중에 5초가 Sleep 상태였어도 API는 10초를 리턴합니다.
            // 따라서, 시간 간격(Interval)을 측정할 때는 이 API를 사용하면 좋습니다.

            val countTimeSeconds = ((currentTimeStamp - startTimeStamp) / 1000L).toInt()

            updateCountTime(countTimeSeconds)

            handler?.postDelayed(this,1000L)
        }
    }

위의 예제는 00:00초에서 시작하여 1초씩 시간이 늘어나는 녹음기 앱을 구현하기 위한 TimeStamp코드이다.

1초씩 딜레이 되는 이벤트를 주기 위해서는 간단하다 

handler? // 만약 핸들러가 Null이 아니라면 .postDelayed(this, 1000L) 1초동안 딜레이를 시키는 방법을 실행시킨다.

 

변형 시켜 적용도 가능하다.

 

3초후에 실행

private Handler mHandler = new Handler();
mHandler.postDelayed(mMyTask, 3000); // 3초후에 실행

private Runnable mMyTask = new Runnable() {
	@Override
	public void run() {
		// 실제 동작
	}
};

 

0.5초 후에 실행하고 실행시 메시지를 전달하며, 실행후 받은 메시지에 따라 처리하는 기능

	new Handler().postDelayed(new Runnable() {// 0.5 초 후에 실행
		@Override
		public void run() {
			// 실행할 동작 코딩
			Message msg1 = mHandler.obtainMessage();  //사용할 핸들러를 이용해서 보낼 메시지 객체 생성
			Bundle b1 = new Bundle();	//메시지를 담을 번들 생성
			b1.putBoolean("END_AUTH", true);	//번들에 메시지 추가
			msg1.setData(b1);	//메세지에 번들을 넣는다.
			mHandler.sendMessage(msg1); 	//메세지를 핸들러로 넘긴다.
		}
	}, 500);	


	Handler mHandler = new Handler() {
		public void handleMessage(Message msg) {  // 실행이 끝난후 확인 가능
        		Bundle bd = msg.getData();
        		if(bd.getBoolean("END_AUTH")){
        			// 메시지를 받고 처리할 부분

        		}
			
		}
	};	

그리고 이제 특정 상황에서 3000이라는 시간이 지나기 전에

실행을 취소하고 싶다면?

if(mHandler != null) {
    mHandler.removeCallbacks(de_at_runnable);
}

Handler에서 가지고 있는 removeCallbacks(Runnable r)을 호출해주면 됩니다.