본문 바로가기
Native 개발/안드로이드 개념 정리

안드로이드 - 핸들러와 Looper의 동작과정

by 번데기 개발자 2019. 1. 28.
반응형

Handler와 Looper의 필요성









Handler와 Looper는 안드로이드 내에서 Thread 백그라운드 처리에 사용됩니다.

위의 그림은 병렬 처리로 돌아가고 있는 Main과 Sub 쓰레드에서 textView의 setText 메서드 사용시 어떤 것을 처리할지에 대한 이미지 인데요,

이런 동기화문제를 처리하기 위해 안드로이드는 메인 스레이드에서만 UI 작업이 가능하도록 제한하였습니다.

Handler와 Looper를 이용해 Sub 쓰레드에서 Main 쓰레드로 UI 처리작업을 전달거나, Main 쓰레드 자체적으로 처리하던지 해야 합니다.




Handler와 Looper의 동작과정







Handler는 단어 그대로 무언가를 처리하는 역활을 합니다.

Handler는 Message와 Runnable 객체를 처리합니다.

Runnable 메세지는 run 메서드를 호출하여 처리하고, Message는 handlerMessage() 메서드를 이용하여 처리합니다.



1. 메세지는 다른 스레드에 속한 Message Queue에서 전달됩니다.

2. MessageQueue에 메세지를 넣을때는 Handler.sendMessage()를 사용합니다.

3. Looper는 MessageQueue에서 Loop()를 통해 반복적으로 처리할 메세지를 Handler에 전달합니다.

4. Handler는 handlerMessage를 통해 메세지를 처리합니다.



중요한 점은 Handler는 의존적이라는 점입니다.

즉 Handler 혼자서는 아무것도 못합니다.

MessageQueue와 그 메세지를 전달해줄 Looper가 없으면 handleMessage()는 사용할 수 없습니다.

즉 Handler는 Thread와 Looper, MessageQueue가 꼭 필요합니다.




Looper의 역활


Looper는 하나의 스레드만 담당할 수 있고, 하나의 스레드도 오직 하나의 Looper만을 가질 수 있습니다.

Looper는 MessageQueue가 비어 있는 동안은 아무 행동도 하지 않고 메세지가 들어오면 해당 메세지를 꺼내 적절한 Handler로 전달합니다.

계속 반복적으로 수행하는 동작 때문에 Looper라는 이름이 지어졌다고 합니다. ^^



Looper의 생성법

Handler는 무조건 Looper와 MessageQueue가 필요하므로 어떤 스레드와 연동되기 위해서는 Looper가 꼭 필요하다는 것을 알 수 있습니다.

그렇다면 스레드에 Looper를 포함시키려면 어떻게 해야 할까요?








특정 스레드 내부에서 Looper.prepare()를 통해 messageQueue를 준비한 뒤 원하는 Handler를 생성합니다.

이후 run() 메소드의 마지막에서 Looper.loop()를 호출함으로써 Message전달을 기다리는 작업이 시작되게 됩니다.

Activity에서 onDestory() 일 때 Handler.getLooper.quit()를 이용해 꼭 종료시켜주는것을 잊지 말하야 합니다.









두번째는 안드로이드에서 제공하는 HandlerThread 클래스를 활용하는 것입니다. 

이는 기본적으로 Looper를 가지고 있고 해당 Thread를 start시키면 자동으로 Loop도 돌기 때문에 편리하게 쓸 수 있습니다.




Handler 단독 사용?


많은 오픈소스를 보면 Handelr를 Looper없이 사용하는 경우가 있습니다.

안드로이드에서는 편리성을 제공하기 위해 Handler의 기본 생성자를 통해 Handler 단독으로 사용할 수 있게 해줍니다.


즉 기본 생성자를 통해 Handler를 생성하면, 생성되는 Handler는 해당 Handler를 호출한 쓰레드의 MessageQueue와 Looper에 자동으로 연결됩니다.







이런식으로 메인 쓰레드에서 Handler를 생성하면 해당 Handler는 호출한 쓰레드의 메세지큐와 루퍼에 자동 연결되므로 다른 쓰레드에서 Handler를 통해 메세지를 전달하면 메인스레드 (UI스레드) 에서 작업이 가능하게 됩니다.


참조)


핸들러 사용법 포스팅)


반응형