새소식

android studio

[android] Handler & Looper

  • -

안드로이드의 UI 동작

안드로이드는 기본적으로 Main Thread (or UI Thread) 하나만으로 구성되는 싱글 쓰레드 모델로 동작한다.

 

 

🤔싱글 쓰레드 모델인 이유 

 

만약 멀티 쓰레드 환경이라면, 여러 쓰레드에서 TextView 의 텍스트를 변경하는 상황이 발생하고 어떤 결과가 나타날 지 미지수이기 때문이다. 따라서 동작의 무결성을 보장하기 위해 타 쓰레드에서는 UI 를 건드릴 수 없고, 오로지 메인 쓰레드에서만 UI 관련 동작을 할 수 있게끔 하는 것이다.

 

✍🏼싱글 쓰레드 모델에서 지켜야할 포인트들

1. 메인 쓰레드 (UI 스레드) 를 블로킹해서는 안 됨

→ 메인 쓰레드를 블로킹한다는 뜻은, 사용자에게 보여지는 UI 동작을 멈춘다는 뜻이다. 메인 쓰레드가 블로킹되어 UI 동작이 멈추게 되면, 이는 표면적으로 앱 퍼포먼스 저하를 유발하게 되며 사용자 경험상 악영향을 끼친다. 따라서, 시간이 오래 걸리는 동작을 수행하는 등 메인 쓰레드를 블로킹해선 안 된다.

2. UI 관련 동작은 오로지 메인 쓰레드에서만 접근해야 함

UI 동작의 무결성을 보장하기 위해서

 

 

🧐Handler & Looper

 메인 쓰레드는 사용자에게 보여지는 UI 동작들을 수행하고  네트워크 작업이나 데이터베이스 작업 등 무거운 동작들은 메인 쓰레드가 아닌 다른 쓰레드에서 처리해주어야 한다. 

하지만 다른 쓰레드에서 수행한 결과 값을 UI에 업데이트하려면 메인쓰레드에 넘겨줘야하는데 어떻게 넘겨주지?

 

이럴 때 사용하는 것이 HandlerLooper라는 장치이다! 

Handler와 Looper는 쓰레드간의 통신이 가능하게 만들어준다. 

 

 

동작부터 봐보자!

1. Thread #2에 있는 메세지(=작업)을 sendMessage() 또는 post 메소드를 통해 전달한다. 
2. sendMessage()로 받은 메세지(=작업)을 꺼내고 Message Queue에 차례대로 넣는다. 
3. Thread #1의 Looper는 Message Queue에서 차례대로 메세지(=작업)을 뽑아 메세지가 Runnable한 객체인경우 run()메소드를 실행, Message 객체인 경우 핸들러로 전달한다.
4. Looper로부터 전달받은 메세지(=작업)을 handleMessage()를 통해 작업을 한다. 

위 과정을 통해 쓰레드 내에서 Handler와 Looper는 쓰레드간 통신을 가능하게 해준다. 

 

**Handler는 MessageQueue 와, MessageQueue 안의 메세지들을 자신에게 전달해주는 Looper 에 의존적인 녀석

 

 

Handler 

특정 메세지(=작업)를 Looper의 Message Queue에 넣거나,
Looper가 Message Queue에서 특정 메세지를 꺼내어 전달하면 이를 처리하는 기능  

 

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

sendMessage() 메소드를 통해 Message Queue에 Message 객체 넣을 수 있음.
post 메소드를 통해 Runnable 객체 넣을 수 있음. 

2. Looper로부터 메세지를 전달받아 처리하는 경우 

Runnable 객체인 경우 : run() 메소드를 호출하여 작업 실행 
Message 객체인 경우 : handleMessage() 메소드를 호출하여 Handler가 메세지 전달 받음 

 

 

 

Looper 

하나의 쓰레드에 오직 하나의 Looper,
Message Queue에 들어오는 메세지들을 하나씩 꺼내어 이를 적절한 Handler로 전달하는 역할 

 

Message Queue: 해당 쓰레드가 처리해야 할 동작들이 '메세지' 형태로 담겨 있다. (FIFO 방식) 

MessageQueue 가 비어있을 땐 아무 동작을 수행하지 않는다.

 

 

 

Message

스레드 간 통신에 사용되는 객체로 작은 작업 단위
사용자 상호작용을 포함한 모든 시스템 이벤트를 전달할 때 사용되는 객체.

 

1. Runnable 객체 
: 핸들러 사용의 주 목적이 메인 스레드의 코드를 실행하는 것일 때 

실행 가능한 작업을 표현하기 위한 인터페이스
Runnable 객체는 run() 메서드를 구현하고 있으며, 해당 메서드가 호출될 때 특정 작업을 수행

 

 

 

2. Message 객체 
:핸들러를 통해 데이터를 전달하여, 전달된데이터 처리를위해 작성된 대상 쓰레드의 코드가 실행되도록 만드는 것

→ 메시지 객체(what, object, arg1, arg2, ...)에 값을 채워 수신 쓰레드의 핸들러에 보내고, 수신 측 쓰레드에서는 handleMessage() 메서드를 오버라이드하여 수신된 메시지 객체를 처리하기 위해 작성된 코드를 실행

 

 

'android studio' 카테고리의 다른 글

[Android] Local Database(SQLite, Room)  (0) 2023.09.12
[android] setValue() , postValue()  (1) 2023.08.09
[android] android service?  (0) 2023.07.21
[android] ViewBinding vs DataBinding ?  (0) 2023.07.12
[android] ViewModel란?  (0) 2023.07.09
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.