본문 바로가기
Development/Android

[안드로이드]핸들러-Handler

by True Life 2015. 12. 17.


안드로이드 프로그래밍 - Handler


오랜만의 포스팅이네요. 오늘은 핸들러에 대해서 포스팅을 해보려고 합니다.


1. 핸들러의 정의(Handler's Definition)


핸들러라고 하면 사실 몇가지 다양한 의미가 있습니다.


인터럽트 핸들러(interrupt handler) : 인터럽트 접수에 대응하여 특정 기능을 처리하는 기계어 코드 루틴

자바 핸들러(java.util.logging.handler) : 자바 프로그램 진행중 발생한 로그를 출력하는 방법을 다루는 클래스

안드로이드 핸들러(android.os.Handler) : 이번에 다룰 핸들러


먼저 안드로이드 핸들러는 쓰레드(Thread)/메시지(Message)/루퍼(Looper)/Runnable/Parcelable 클래스 등과 관련이 있습니다.

글을 읽다가 이해가 안가신다면 내용을 알아보고 오시면 좋을듯 합니다.


1. [자바-Java]쓰레드- Thread

2. [자바-Java]메시지-Message

3. [안드로이드-Android]-핸들러(Handler)와 루퍼(Looper)

4. [자바-Java]Runnable과 쓰레드(Thread)의 관계

5. [안드로이드-Android]Parcelable 인터페이스

6. [자바-Java]콜백-Callback


핸들러는, 안드로이드 어플리케이션 프레임워크에서 제공되는 매우 유용하여 사용 빈도가 높은 클래스 중 하나입니다.

이 핸들러의 목적은 Message나 Runnable이라는 Object를 전달/처리해주는 역할을 수행합니다.

자 항상 무언가를 전달을 한다면 Source와 Destination이 있어야겠죠. 핸들러에서의 출발/도착은 각 Thread가 됩니다.


프로그램을 생성하면 Main Thread가 만들어집니다. 거기에 프로그래머의 의도에 따라 Sub Thread들이 만들어지죠.

그런데 지금 다루는 Java는 객체지향언어(Object Oriented Programming)입니다. 따라서 Sub Thread라는 객체는 Main Thread 소속의 객체들(이를테면 UI등)을 변경할 권한이 없습니다! (캡슐화 - private)

* 안드로이드에서 UI화면은 Main Thread만 접근할 수 있도록 막아 두었습니다. (안정성을 위해서라 합니다)


이 규칙 때문에 Sub Thread에서 Main Thread에 있는 객체에 대해 접근을 시도하기 위해서는 Main Thread에게 '요청'을 해야합니다.

이 요청의 데이터가 바로 앞서 말씀드렸던 Message, Runnable의 Object 입니다.


1. [자바-Java]클래스간 소통(Communication)

2. [자바-Java]캡슐화(Encapsulation)

3. 객체지향언어(Object oriented programming, OOP)


이 구도를 잠시 그림으로 표현해 보도록 하겠습니다.


이 그림으로 핸들러에 대한 개략적인 내용이 이해됬으리라 믿습니다. 이 과정을 소스로 한번만 살펴보겠습니다.



2. 핸들러의 원리(Handler's Principle)


자 그렇다면 핸들러는 어떤 구조로 동작하는 걸까요, 원리에 대해 조금만 더 설명하겠습니다.

핸들러는 기본적으로 Thread와 Looper, MessageQueue와 매우 밀접한 관련이 있습니다. 여기서도 Looper+MessageQueue=Handler 라고 말할 수 있을 정도로 이 두 클래스에 루틴의 과정이 들어있는 겁니다.

기본 생성자를 통해 Handler를 생성하면, 새롭게 생성된 Handler는 해당 생성자가 호출된 그 Thread의 MessageQueue, Looper에 자동으로 연결됩니다.


여기서는 MessageQueue, Looper, Handler가 개별적이게 표현되었는데 실제로는 Handler를 선언하면 모든게 연결됩니다.


3-1. 핸들러의 사용(Use of Handler) #1


자, 핸들러를 이해했으면 써먹어야겠죠, 핸들러의 응용은 수도 없지만 두가지 대표적 예를 보겠습니다.


현실적인 예를 위해서 실제 게임에 사용되어 있던 일부분을 긁어왔습니다. (본 함수/변수들을 전부 집필하지 않았기에 원리만 파악해 보세요^^;)

이 예제는 '루프'에의 이용입니다. 일정 시간(예제에서는 0.1sec) 반복 처리를 위해 핸들러를 사용했죠. sleep이 호출되면 0.1초 후에 다시 자기 자신을 호출하라는 메세지를 보냅니다. 위 소스에서는 Runnable을 넘기지 않고 Message를 넘겼습니다. 여기서 Message는 큰 의미가 없습니다. '호출'된 그 자체에 의미가 큰 것이죠.


여기서 핸들러의 sendMessge에 대한 메소드를 조금 소개하겠습니다. (메소드명이 직관적 의미이므로 해석은 생략합니다)


1. sendMessageDelayed(Msg, delayTime);

2. sendMessageAtFrontOfQueue(Msg);

3. sendMessage(Msg);

<구글 API - Handler>


3-2. 핸들러의 사용(Use of Handler) #2


이번에는 Runnable을 넘기는 예제를 보겠습니다. 처음 보여드린 소스도 Runnable을 이용했습니다. 이 예제를 보시고 위로 올라가서 소스를 다시 분석해 보시는걸 추천합니다.


이렇게 Runnable을 통해 UI를 바꾸는 예제까지 보여드리는 것으로 이번 포스팅을 마치겠습니다.

핸들러를 공부하신김에 루퍼/콜백에 대해 조금 더 공부해보고 싶으신 분들을 위해..


[안드로이드-Android]-핸들러(Handler)와 루퍼(Looper)

[자바-Java]콜백-Callback