앱 개발자라면 Thread는 필수겠죠?
안드로이드를 배우다 보면 Thread를 접하게 되는데 안드로이드에는 두 가지 Thread가 존재합니다.
- Main Thread(Ui Thread)
- Worker Thread(Sub Thread)
이 두 가지 스레드는 각각 다른 역할을 하는데
예를 들어 TextView를 수정할 때 여러 스레드에서 한 개의 TextView에 setText를 한다면
Exception이 발생하게 됩니다.
이를 막기 위해 안드로이드는 시스템 상에서 UI작업은 Main Thread에서만 처리하도록 설계 되어 있습니다.
그럼 이제 Thread에 대해서 알아보면
Thread를 구현하는 방법은 Thread 클래스를 상속받는 것과 , Runnable 인터페이스를 구현하는 방법, 모두 2가지가 있습니다. 이 두가지 방법 중 어느 쪽을 사용해도 별 차이는 없지만 Thread 클래스를 상속받으면 다른 클래스를 상속받을 수 없기 때문에 , Runnable 인터페이스를 구현하는 것이 일반적입니다.
thread.start()
메소드로 스레드를 시작
Override된run()
메소드가 반복 실행됩니다.
처음에 말했다시피 안드로이드는 Main Thread에서만 UI작업을 해야 합니다.
근데 만약 Worker Thread에서 UI작업을 해야 한다면 어떻게 해야 할까요??🤔
바로 Handler를 사용 해야 합니다!😲
안드로이드는 UI작업을 비동기적으로 처리할 때 동기화 문제를 예방하기 위해 병렬로 동작하는 메인 스레드와 워커 스레드 사이에 핸들러를 두고 UI 작업은 모두 메인 스레드로 전달하도록 되어 있습니다.
- Handler의 역할은 메시지를 전달하는 것
워커 스레드에서 핸들러는 메인 스레드로 메시지를 전달, 이후 메시지를 수신한 메인 스레드에서 적절한 작업을 처리합니다.- 메인 스레드에서 무거운 작업은 하지말 것
안드로이드는 메인 스레드에서 UI 작업을 처리합니다. 그렇기 때문에 시간이 오래 걸리는 작업을 메인 스레드에서 하게 된다면 UI 처리가 늦게 이뤄지게 되겠죠??
핸들러 사용의 주 목적이 대상 스레드의 코드를 실행하는 것이라면, 메시지를 통해 데이터를 전달하는 번거로운 과정을 거치지 말고, 그냥 "실행 코드"를 바로 보내면 되지 않을까요? 즉, 핸들러에 실행 코드가 담긴 객체를 보내고, 대상 스레드에서는 수신된 객체의 코드를 직접 실행하도록 만드는 것입니다.
여기서 말하는 "실행 코드가 담긴 객체". 그것이 바로 Runnable 객체입니다.
메세지.. 문자 메세지?
안드로이드의 스레드 통신에서는 위에서 알아본 핸들러를 통해 데이터를 보낸다고 했죠.
이때 데이터 종류를 식별할 수 있는 식별자와 실질적인 데이터를 저장한 객체, 그리고 추가 정보를 전달할 객체가 필요합니다.
즉, 전달할 데이터를 한 곳에 저장하는 역할을 하는 클래스가 필요한데요, 이 역할을 하는 클래스가 바로 Message 클래스입니다.
메세지 큐의 Queue는 우리가 자료구조에서 흔히 보는 그 Queue 선입선출.. 맞습니다.
TMI: 리그오브레전드라는 게임에서 흔히 말하는 "큐 잡는다" 할때 그 큐도 같은.. Queue
MessageQueue는 이름 그대로 Message 객체를 큐(Queue) 형태로 관리하는 자료 구조를 말합니다.
큐(Queue)라는 이름답게 FIFO(First In First Out) 방식으로 동작하기 때문에, 메시지는 큐에 들어온 순서에 따라 차례대로 저장됩니다. 그리고 가장 먼저 들어온 Message 객체부터 순서대로 처리됩니다.
MessageQueue는 Message 객체 리스트를 관리하는 클래스일 뿐, 큐에 쌓인 메시지 처리를 위한 핸들러를 실행시키지는 않습니다.
메시지 루프, 즉, 메시지 큐로부터 메시지를 꺼내온 다음, 해당 메시지와 연결된 핸들러를 호출하는 역할은 루퍼(Looper)가 담당합니다.
즉, 메시지 처리를 위한 메시지 루프(Message loop)를 실행합니다.