Looper?
- (loop)+er 뭔가 반복해서 실행하는 것
- TLS(thread local storage)에 저장되고 꺼내어진다.
- ThreadLocal<Looper> 에 set() 메서드로 새로운 Looper을 추가하고, get() 메서드로 스레드별로 다른 Looper가 반환된다.
- Loper 별로 MessageQueue를 가짐
Looper에게 MessageQueue란
Looper는 MessageQueue를 통해서 UI 작업에서 경합 상태를 해결한다. MessageQueue에서 꺼낸 Message가 null이 될 때는 Looper가 종료될 때이다.
quit()와 quitSafely() 메서드 차이
둘 다 Looper를 종료시키는 메서드다.
quit()는 아직 처리되지 않은 Message를 모두 제거한다. quitSafely() 메서드는 sendMessageDelayed()등을 써서 실행 타임 스탬플르 뒤로 미룬 지연 Message를 처리하는데, quitSafely() 메서드를 실행하는 시점에 현재 시간보다 타임 스탬프가 뒤에 있는 Message를 제거하고 그 앞에 있는 Message는 계속해서 처리한다.
Message와 MessageQueue
이름에서 알 수 있다시피 MessageQueue는 Message를 담는 자료구조이다.
Message를 생성할 때는 오브젝트 풀(object pool)에서 가져오는 Message.obtain() 메서드나 Handler의 obtainMessage() 메서드를 사용을 권장한다. new Message()를 통해 생성해도 동작에는 문제 없어보이지만 Message 처리가 끝나면 불필요하게 풀에 Message를 추가하면 금방 풀의 최대 개수에 이른다. 따라서 자원이 낭비된다.
Handler ?
Handler는 Message를 MessageQueue에 넣는 기능과 꺼내 처리하는 기능을 함께 제공한다.
백그라운드 스레드에서 Looper를 지정하지않은 Handler()를 사용한다면 RuntimeException이 발생한다. Looper.prepare()를 실행하여 Looper를 준비해야하기 때문이다.
Handler 동작
여러가지 동작이 있지만 -Delayed로 끝나는 메서드는 내부적으로 -AtTime() 메서드를 호출한다.
sendMessageFrontOfQueue(), postAtFrontOfQueue()는 되도록 쓰지말아야 한다.
dispatcheMessage()는 퍼블릭 메서드로 MessageQueue를 거치지 않고 직접Message를 처리한다.
핸들러의 지연 메서드인 -Delayed()나 -AtTime() 메서드는 지연시간을 정확히 보장하진 않는다. MessageQueue에서 먼저 꺼낸 Message 처리가 오래걸린다면 실행이 당연히 늦어진다.
참고 자료:
안드로이드 프로그래밍 Next Step
'안드로이드' 카테고리의 다른 글
Context 클래스 (0) | 2022.02.04 |
---|---|
AsyncTask (0) | 2022.01.25 |
안드로이드 호환성 모드 (0) | 2021.12.02 |
StateFlow를 알아가는 과정 (Flow, LiveData) (0) | 2021.06.10 |
Dagger2 - Android (0) | 2021.04.22 |