안드로이드
[스크랩] 스레드 - 핸들러 - 루퍼(Looper)
start1a
2020. 1. 12. 20:47
https://itmining.tistory.com/5
[안드로이드] Thread, Handler, Looper를 통한 백그라운드 처리
이 글은 PC 버전 TISTORY에 최적화 되어있습니다. 서론 안드로이드의 UI는 기본적으로 메인스레드를 주축으로하는 싱글 스레드 모델로 동작하므로, 메인 스레드에서는 긴 작업을 피해야 합니다. 즉 긴 작업은 여분..
itmining.tistory.com
안드로이드 UI
- 기본적으로 메인 스레드를 중심으로 하는 싱글 스레드 모델
- 긴 작업은 다른 곳에서 하고 메인 스레드와 같은 UI 스레드에서는 UI 변경만 담당하도록 스레드 간의 통신 유도
핸들러 (Handler)
- Message나 Runnable 객체를 받아 다른 곳으로 전달함
- 이미지를 받아 UI에 표시할 때, AsyncTask와 더불어 사용
Handler와 Looper를 사용하는 이유
두 스레드에서 병렬 처리로 UI를 변경할 때 동기화 문제 해결을 위해 안드로이드에서는 메인 스레드에서만 UI 작업이 가능하도록 제한하고 있기 때문이다. Sub Thread에서 UI 작업 시 Handler와 Looper를 이용해 Main Thread로 작업할 메시지를 전달하거나 Main Thread 내에서 자체적으로 처리하여야 한다.
Handler와 Looper의 동작 과정
Handler의 처리 방법
- Runnable 메시지는 run() 메서드를 통해 처리
- Thread(Runnable runnable) 생성자로 Runnable 인터페이스를 구현한 개체를 생성
- 이 개체를 상속받은 스레드는 추상 메서드 run()을 반드시 구현해야 함
- Message는 handleMessage() 메서드를 통해 처리
- 메시지는 다른 스레드에 속한 Message Queue에 전달됨
- Message Queue에 메시지를 넣을 땐 Handler의 sendMessage()를 이용함
- Looper는 Message Queue에서 Loop()를 통해 반복적으로 처리할 메시지를 Handler에 전달함
- Handler는 handleMessage()를 통해 메시지를 처리함
Looper
- 하나의 스레드만 담당할 수 있음. 스레드도 하나의 Looper만 가짐
- Message Queue가 비었으면 대기하고 메시지가 들어오면 메시지를 꺼내 적절한 Handler로 전달
- 이 행동을 반복적으로 수행하므로 Looper라고 함
Looper 생성 방법 2가지
1.
1
2
3
4
5
6
7
8
9
|
Thread t = new Thread(new Runnable(){
@Override
public void run() {
Looper.prepare();
handler = new Handler();
Looper.loop();
}
});
t.start();
|
- 특정 스레드 내부에서 Looper.prepare() : Message Queue 준비
- handler = new Handler() : 원하는 핸들러 생성
- Looper.loop() : 메시지 전달을 기다리는 작업 시작
- Activity onDestory() 시 handler.getLooper().quit()를 사용해 반드시 종료할 것!
2.
HandlerThread t = new HandlerThread("My Handler Thread");
t.start();
handler = new Handler(t.getLooper());
- 안드로이드에서 제공하는 HandlerThread 클래스 활용
- HandlerThread 클래스가 내부에 기본적으로 Looper를 가짐
- 해당 스레드 start하면 자동으로 Loop도 실행되어 매우 편리
Handler 단독 사용
- Handler를 Looper 없이 사용하는 경우가 많음
- 안드로이드에서 편의성을 제공하기 위해 Handler의 기본 생성자로 생성 시 단독 사용 가능
- Handler를 생성한 스레드의 Message Queue와 Looper에 자동 연결됨
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
public class MainActivity extends AppCompatActivity {
Handler mHandler = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHandler = new Handler();
Thread t = new Thread(new Runnable(){
@Override
public void run() {
// UI 작업 수행 X
mHandler.post(new Runnable(){
@Override
public void run() {
// UI 작업 수행 O
}
});
}
});
t.start();
}
|
- 메인 스레드에서 Handler 생성
- 해당 Handler는 호출한 스레드(메인 스레드)의 Message Queue, Looper가 자동 연결됨
- 다른 스레드에서 Handler를 통해 메시지 전달 -> 메인 스레드에서 UI 작업 가능