Android

Android의 Handler 와 Looper

태인킴 2020. 10. 6. 11:51
반응형


핸들러와 루퍼

안드로이드 시스템에서 UI 관련 작업Main Thread(UI Thread) 에서 처리해야 합니다. 시간이 오래 걸리는 네트워크 작업이나 테이터베이스 작업들은 별도의 스레드(Worker Thread)에서만 작업을 해야 합니다. 따라서 다운로드 작업, 네트워크 작업은 Worker Thread에서 수행하고, 작업한 결과를 UI에 출력해 주어야 합니다. 이 때 서로 다른 스레드간 통신 작업을 해주어야 합니다. 이때 필요한 것이 핸들러(Handler)와 루퍼(Looper) 입니다. 또한, 아래 그림을 보면 알수 있지만, Handler는 '멀티 스레드 생산자-소비자 디자인 패턴' 을 따르고 있습니다. 여기서, Handler생산자(Producer)도 되고, 소비자(Consumer)도 될수 있습니다.

 

 

1. Handler가 sendMessage()를 통해서 Message를 Message Queue에 전달 합니다.
2. Looper가 Message Queue에서 Message를 handleMessage()를 통해서 Handler에게 전달 합니다.

 

 

루퍼(Looper)

스레드 당 하나의 루퍼를 가질 수 있습니다. Message가 들어오면 해당 메세지를 Handler 에게 전달 합니다. 새로 생성한 스레드는 루퍼를 가지고 있지 않습니다. Looper.prepare() 메서드를 통해 Looper를 생성 할 수 있습니다. Looper는 Message Queue를 가지고 있고, Message가 들어오는지 감시하고, 들어온 Message를 Handler에게 전달 합니다.

 

 

핸들러(Handler)

Handler의 기본 생성자Looper를 인자로 받거나, 비어 있습니다. 비어 있는 Handler는 자신을 호출한 Thread의 Looper를 사용 합니다. 만약 Main Thread에서 Handler를 인자가 비어 있는 생성자로 생성하여 호출 한다면, 이 Handler는 Main Looper를 사용하게 될 것 입니다. 이러한 Main Looper를 가지고 있는 Handler가 주로 UI 갱신 작업을 할 때 사용 됩니다.

 

 

핸들러 스레드(Handler Thread)

Main Thread는 기본적으로 Looper가 생성되어 있습니다. 하지만, 일반 Thread는 Looper를 가지고 있지 않습니다. 따라서, Thread를 상속하고 Looper.prepare(), Looper.loop()을 호출하는 HandlerThread가 존재 합니다.

 

 

 

메세지 큐(Message Queue)

무제한 단방향 연결 리스트 입니다. LinkedBlockingQueue 유사한 구현체 입니다.

 

 

메인 루퍼(Main Looper)

메인 루퍼는 어플리케이션이 시작 할 때 Main Thread 의 하나의 Main Looper를 가지고 있습니다. UI 갱신을 위해 Worker Thread가 Main Thread에게 보낸 Message를 처리하게 되는 경우, Main Thread는 '멀티 스레드 생산자 - 소비자 패턴'의 소비자 스레드(Consumer)의 해당 됩니다. Looper.getMainLooper()를 이용해서 모든 스레드는 Main Looper에게 Message를 전달 할 수 있습니다. 또는, runOnUiThread()를 Worker Thread에서 Main Looper의 MessageQueue에게 Message를 전달 할수도 있습니다.

 

 

CalledFromWrongThreadException

만약 UI 갱신 작업을 Main Thread 에서 하지 않는다면, CalledFromWrongThreadException이 떨어질 것 입니다.

반응형