ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Handler와 Looper
    안드로이드 학습/Android 기술면접 대비 2024. 8. 20. 17:22

    UI 업데이트를 메인 스레드에서만 허용한다. 하지만 메인 스레드 이외의 스레드에서 UI 처리를 해야 한다면 해당 스레드와 UI 스레드를 이어주는 것이 handler이다.

     

    메인 스레드 :

    더보기

    앱 프로세스가 시작되면서 Main Thread(메인 스레드)가 생성된다. 컴포넌트의 생명주기 메서드와 그 안의 메서드 호출은 기본적으로 메인 스레드에서 실행된다. 메인 스레드는 UI를 변경할 수 있는 유일한 스레드이기 때문에 메인 스레드를 UI 스레드로 부르기도 한다.

     

    UI 작업을 UI / Main Thread에서만 하는 이유?

    • UI 작업을 Worker Thread(새로 생성된 스레드)에서 비동기적으로 처리한다면 동기화 문제에 마주치게 될 것이다 .

    • 안드로이드는 이런 문제를 막기위해 병렬 동작하는 Main Thread와 Working Thread 사이에 Handler를 두고 UI 작업은 모두 Main Thread로 전달하게 하였다.

    Handler 사용시

    • Main Thread 무거운 작업을 X : Main Thread에서 UI 작업이 이루어진다. 시간이 오래 걸리는 작업을 메인 스레드에서 하게 되면 UI 처리가 늦어진다.

     

    하나의 Handler는 하나의 thread와 연결되어있다. Handler를 만들면 이때 하나의 Looper 와 연결이 되고, Handler를 통해서 Looper의 메시지 큐에 message를 전달 해서 Looper의 thread에서 수행이 되게 된다.

    handler를 사용해서 메시지를 보내는 방식으로 thread간에 통신을 쉽게 해준다.

    핸들러를 통한 스레드간 통신

    1. 핸들러에 있는 sendMessage()를 통해서 Message(=작업)를 전달합니다.
    2. 그럼 핸들러는 Message Queue에 차례대로 넣습니다.
    3. 그럼 Looper가 Message Queue로부터 하나씩 Message를 뽑아서 핸들러로 전달합니다.
    4. Looper로부터 전달받은 메시지는 handleMessage()를 통해서 작업을 하게 됩니다.

    Handler :

    • 특정 메세지를 Looper 의 MessageQueue 에 넣거나, Looper 가 MessageQueue 에서 특정 메세지를 꺼내어 전달하면 이를 처리하는 기능을 수행한다. 
    • 루퍼(looper)에 의해 메시지 큐에 쌓인 메시지가 감지되면, 핸들러(Handler)라는 클래스에 의해 해당 이벤트가 실행되게 된다.

    Looper 로 메세지를 전달하는 경우

    • sendMessage() 메소드를 통해 메세지 큐에 Message 객체를 적재할 수 있다.
    • post 로 시작하는 메소드들을 통해 Runnable 객체를 직접 적재할 수 있다.

    Looper 로부터 메세지를 전달받는 경우

    Looper 가 메세지 큐에서 메세지 하나를 딱 꺼냈을 때,

    • Runnable 객체가 담겨있다면 해당 Runnable 의 run() 메소드를 호출하여 작업을 실행할 수 있다.
    • Message 객체가 담겨있다면 해당 메세지 내부의 Handler 가 갖고 있는 handleMessage() 메소드를 호출함으로써 해당 Handler 가 메세지를 전달받을 수 있다.

    Looper :

    • Looper 클래스는 Message Queue를 생성하고 관리하는 역할로 Message나 Runnable 객체를 하나씩 꺼내서 Handler에 전달합니다
    • 하나의 쓰레드에는 오직 하나의 Looper 를 가지며, Looper 는 오직 하나의 쓰레드를 담당한다. 안드로이드에선 기본적으로 MainActivity가 실행됨과 동시에 자동으로 메인 쓰레드의 Looper 가 돌기 시작한다.
    • 각 쓰레드의 Looper 내부에는 MessageQueue 라는 것이 존재하는데, 여기에는 해당 쓰레드가 처리해야 할 동작들이 '메세지' 라는 형태로 하나씩 쌓이게 된다. (큐 라는 이름에서 알 수 있듯 당연히 FIFO 방식이다)
    • 메인 스레드에는 Looper가 기본적으로 생성되어 있지만, 새로 생성한 스레드는 Looper를 가지고 있지 않기 때문에 메시지를 받을 수 없다. 사용할 수 있는 메시지 큐가 없기 때문이다. 서브 스레드에서 메시지를 전달받기 위해서는 Looper를 생성해주어야 함 (but, Looper 자동 보유클래스-> HandlerThread)
    • 주로 메인 쓰레드의 Looper 는 보통 UI 작업을 위한 메세지를 처리하게 된다.

    Message Queue : 

    • Message queue는 핸들러가 전달하는 Message를 보관하는 FIFO방식의 큐이다. 
    • 개발자가 MessageQueue 객체를 직접 참조하여 메시지를 전달하거나, 메시지를 가져와서 처리하지는 않습니다. 메시지 전달은 메시지 큐에 연결된 핸들러(Handler)를 통해서, 그리고 메시지 큐로부터 메시지를 꺼내고 처리하는 역할은 Looper가 수행하기 때문입니다.
Designed by Tistory.