Message Passing with Thread 메인 스레드에서 다른 스레드로 메세지(데이터) 보내기
Android 2022. 2. 14. 10:32 |반응형
Message, Handler, 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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
package com.example.myapplication;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
EditText editText;
TextView textView;
MyThread myThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = findViewById(R.id.editText);
textView = findViewById(R.id.textView);
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String input = editText.getText().toString();
Message message = Message.obtain();
message.obj = input;
myThread.handler.sendMessage(message);
}
});
myThread = new MyThread();
myThread.start();
}
class MyThread extends Thread {
Handler handler;
@Override
public void run() {
handler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
textView.setText(msg.obj + " from My Thread.");
// 메인 스레드의 메인 루퍼를 사용하기 때문에
// textView()에 바로 접근 가능하다.
}
};
}
}
}
|
메인 루퍼를 이용하는 소스를 작성하고 빌드한다.
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
package com.example.myapplication;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
EditText editText;
TextView textView;
MyThread myThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = findViewById(R.id.editText);
textView = findViewById(R.id.textView);
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String input = editText.getText().toString();
Message message = Message.obtain();
message.obj = input;
myThread.handler.sendMessage(message);
}
});
myThread = new MyThread();
myThread.start();
}
class MyThread extends Thread {
Handler handler;
@Override
public void run() {
Looper.prepare();
handler = new Handler(Looper.myLooper()) {
// 메인 스레드가 아닌 새로 만든 이 스레드의 루퍼 사용
@Override
public void handleMessage(@NonNull Message msg) {
String message = msg.obj.toString();
// 새로 만든 이 스레드로 넘어온 메세지 데이터를 미리 처리.
// 아래 setText()에서 msg.obj를 사용하면 null 값이 대입된다.
textView.post(new Runnable() {
@Override
public void run() {
textView.setText(message + " from My Thread");
}
});
}
};
Looper.loop();
}
}
}
|
메인 루퍼가 아닌 새로 만든 스레드의 루퍼를 생성하고 메세지를 처리하는 소스. 결과는 동일하다.
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
package com.example.myapplication;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
EditText editText;
TextView textView;
MyThread myThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = findViewById(R.id.editText);
textView = findViewById(R.id.textView);
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String input = editText.getText().toString();
Message message = Message.obtain();
message.obj = input;
myThread.myHandler.sendMessage(message);
}
});
Button button2 = findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
myThread.myHandler.StopLooper();
// 새로 만든 스레드의 루퍼 종료.
}
});
myThread = new MyThread();
myThread.start();
}
class MyThread extends Thread {
MyHandler myHandler;
@Override
public void run() {
Looper.prepare();
myHandler = new MyHandler();
Looper.loop();
}
class MyHandler extends Handler {
MyHandler() {
super(Looper.myLooper());
}
@Override
public void handleMessage(@NonNull Message msg) {
String message = msg.obj.toString();
// 새로 만든 이 스레드로 넘어온 메세지 데이터를 미리 처리.
// 아래 setText()에서 msg.obj를 사용하면 null 값이 대입된다.
textView.post(new Runnable() {
@Override
public void run() {
textView.setText(message + " from My Thread");
}
});
}
void StopLooper() {
myHandler.getLooper().quitSafely();
// 새로 만든 스레드의 루퍼 종료.
}
}
}
}
|
새 스레드의 루퍼를 종료하는 함수가 포함된 파생 Handler 클래스를 사용하는 소스.
Looper.XXX() 호출 시 MyThread 클래스 내부라도 어디서 루퍼를 참조 하느냐에 따라 메인 루퍼가 참조 될 수도 있고 새 스레드의 루퍼가 참조 될 수 있다. (MyThread.Run()에서만 새 스레드의 루퍼가 참조된다)
※ 참고
반응형
'Android' 카테고리의 다른 글
Execute Adb Shell Command 안드로이드 리눅스 커널 명령 실행 (1) | 2022.04.20 |
---|---|
Text To Speech 안드로이드 TTS (0) | 2022.02.14 |
User Interface Manipulation From UI Thread - 다른 스레드에서 UI 객체 접근하기 (0) | 2022.02.13 |
Google Android Maps SDK 구글 안드로이드 맵 (0) | 2022.02.12 |
Linux(Ubuntu) Database Server with PHP For Android App - 안드로이드 앱을 위한 리눅스(우분투) 데이터베이스 서버 (0) | 2022.02.09 |