쓰레드, 스레드, Thread, 핸들러, Handler
각 쓰레드는 고유 스택을 가진다.
Main 쓰레드(쓰레드 생성자)와 별도의 CPU 시간을 할당 받음.
쓰레드로 구현할 코드는 run() 에 넣는다.
start() 호출하면 run() 자동 실행.
setDaemon(true) : Main 쓰레드 종료되면 호출된 쓰레드 자동 종료.
A. Thread 상속받아 구현
다른 클래스 상속을 못받음.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
TextView output; ConnectSocket conSock = new ConnectSocket(); conSock.setDaemon(true); // 메인쓰레드 종료되면 쓰레드 자동종료시킴 conSock.start(); class ConnectSocket extends Thread { public void run() { while (true) { .... output.post(new Runnable() { public void run() { output.setText(c); } }); } } } |
9번 부터 쓰레드 클래스 정의하고
5번에서 쓰레드 객체 만들고 7번에서 쓰레드 실행한다.
쓰레드에서 처리할 코드는 12번에 넣는다.
B. Runnable 로 구현
다른 class 상속받아 수정이 필요한경우 class 상속받고, runnable 구현
1 2 3 4 5 6 7 8 9 10 11 12 |
BackRunnable r = new BackRunnable();
Thread t = new Thread(r); t.setDaemon(true); t.start(); class BackRunnable implements Runnable { public void run() { .... } } |
C. Handler 쓰레드간 데이터 주고받기 (윈도우의 메시지 처리기와 유사)
- 쓰레드간 Msg 전달
- 하나의 쓰레드를 가짐 (1:1 매칭)
- sub 쓰레드는 Main 쓰레드의 값을 참조 가능하나 Main 쓰레드의 UI 출력은 불가하므로
이때 handler 로 값을 전달하여 Main 쓰레드에서 값을 받아 출력하면 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
TextView m; int mValue; class ConnectSocket extends Thread { public void run() { h.sendEmptyMessage(0); // 메시지 전달하면 자동으로 handlerMessage() 호출됨 // m.setText(mValue); // 오류 발생하므로 handler 이용 } } Handler h = new Handler() { public void handlerMessage(Message msg) { if (msg.what == 0) { // 메시지 종류에 따라 처리, 여러 쓰레드에서 handler 공유 할때 이용 m.setText(mValue); } } }; |
D. 루퍼, Looper (윈도우의 이벤트 처리기와 유사)
- Msg Queue 에 메시지 전달되면 handler 가 스스로 가져가지 못하므로 Looper 가 쓰레드로 전달해준다.
- App 실행 시 생성되는 Main 쓰레드는 루퍼를 가지고 있으나, 쓰레드는 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 |
TextView m;
int mValue; class ConnectSocket extends Thread { Handler MainHandler; ConnectSocket(Handler h){ // 생성자 MainHandler = h; } public void run() { Looper.prepare(); // 메시지 큐 생성 Looper.loop(); } } Handler h = new Handler() { public void handlerMessage(Message msg) { Message msg = Message.obtain(); // 매번 new 연산자 쓰면 메모리 낭비, 속도저하문제로 이걸쓴다. // 전달하는 값이 없는 경우 인수없이 호출 if (msg.what == 0) { m.setText(mValue); } } MainHandler.semdMessage(msg); // Main 쓰레드로 메시지 전달 }; |
Message.obtain(handler 부모핸들러, int what, int arg1, int arg2, Object obj);
부모핸들러.sendMessage(msg);
- what : 여러 쓰레드에서 하난의 핸들러 공유 시 쓰레드 구분자 역활
- 정수형 전달은 arg1, arg2 이용
- 3개 이상 전달 혹은 int형 이외의 자료형을 전달시에는 obj 이용