[Android/안드로이드] Thread/Handler/Looper

JINA·2021년 9월 27일
0

Android/basic

목록 보기
5/6

✍키워드 정리

  • 프로세스 : 실행 중인 프로그램 ex) 실행중인 인스타그램
  • 프로세스는 (다수의) 작업 단위 집합
  • 스레드(Thread) : 하나의 프로세스 상의 독립적인 실행 흐름 ex) 좋아요 기능, 스토리 공유 기능 등
  • 하나의 프로세스에는 메인스레드만 있거나 메인스레드 + 서브스레드로 구성
  • 백그라운드 스레드는 UI요소를 직접 접근 못함
  • 백그라운드 스레드와 메인스레드를 연결해 주는 것은 핸들러

Thread

안드로이드는 기본적으로 하나의 메인 스레드로 작동한다. 안드로이드의 스레드는 ① 메인 스레드와 ② 백그라운드 스레드로 나눌 수 있다. 메인스레드는 1개만 존재하고, 백그라운드 스레드는 여러 개가 존재할 수 있다.

1. 메인 스레드(UI 스레드)

  • UI조작은 메인 스레드만 가능하다.
  • 안드로이드 UI 구성 요소와 상호작용하고, UI 이벤트를 사용자에게 응답하는 스레드이다.
  • UI 이벤트 및 작업에 대해 오래 걸리면 안드로이드 시스템은 ANR(어플리케이션 응답 없음) 오류가 생긴다.

2. 백그라운드 스레드

  • 백그라운드 스레드는 UI조작을 할 수 없다.
  • 백그라운드 스레드에서는 처리 시간을 미리 계산할 수 없는 작업의 처리가 권장된다.
  • 백그라운드 스레드는 Thread 클래스를 상속받거나 Runnable 인터페이스를 구현해 생성할 수 있다.

-> 이러한 멀티 스레드 환경에서 동기화 이슈를 차단하고 스레드간의 통신을 위해 사용되는 것이 핸들러와 루퍼이다.

Handler

핸들러(Handler) : 받은 메세지를 처리하고 스레드간의 메세지를 전달하는 작업을 수행함

핸들러를 생성하면 핸들러를 생성한 스레드와 루퍼에 연결된다. 핸들러에는 postDelayed와 같은 메세지의 순서나 보내는 시간을 조작하는 함수를 가지고 있어서 스케줄링을 할 수 있다는 장점이 있다.

Looper

루퍼(Looper) : 같은 작업을 계속 수행함. 메세지큐에서 차례대로 메세지와 runnable 객체를 꺼내서 핸들러에게 전달함.

하나의 스레드에는 오직 하나의 Looper 를 가지며, Looper 는 오직 하나의 스레드를 담당한다. Looper는 스레드간의 신호이므로 handler에 보낸다고 해서 곧바로 처리되는 것이 아니다. 동시다발적으로 메세지가 발생할 수 있기 때문에 메세지 큐(Message Queue)에 쌓았다가 처리한다. 큐(Queue)에 들어있는 내용을 하나씩 꺼내 처리하는 것이 루퍼이다. 메인 쓰레드가 looper를 가지고 있으며 무한 루프를 돌며 큐의 내용을 처리한다.

사용 예제

안드로이드에서는 별도 스레드의 결과를 메인 스레드에서 처리하므로 Main Looper를 명시하여 Handler 생성한다.

var handler: Handler? = null
val thread = Thread {  
    handler = Handler(Looper.getMainLooper())
}
thread.start()

postDelayed를 사용하여 2초후 작업할 수 있도록 스케줄링하는 예시

lateinit var runnable: Runnable
var handler: Handler? = null

handler = Handler(Looper.getMainLooper())
        runnable = Runnable {
           //UI작업
        }
        handler!!.postDelayed(runnable, 2000)

0개의 댓글