안드로이드 - Thread간 통신 및 데이터 전달 방법
목차
- Thread간 통신의 필요성
- Thread간 통신방법 (데이터 전달 방법)
- Thread간 통신예제
- Message객체 전달 방법 - sendMessage( ) 사용
- Runnable 객체 전달 방법 - post( ) 사용
- Runnable 객체 전달 방법 - runOnUiThread( ) 사용
1. Thread간 통신의 필요성
안드로이드에서 처음 스레드(Thread)를 만들어서 사용하게 되면, 대부분 다음과 같은 상황에 마주하게 됩니다.
- 시간이 오래 걸리는 작업을 메인스레드에서 동작시켜 에러 발생
- 메인스레드의 제약 사항을 인지하고 작업자 스레드(Worker Thread)를 만들어 사용함
- 작업자 스레드(Worker Thread)에서 화면 UI 작업을 실행시켜 또 다른 에러 발생
- 작업자 스레드에서의 결과를 화면에 보여주기 위해 메인 스레드(UI 스레드)로의 데이터 전달이 필요함을 인지
위 예시와 같이 메인 스레드(UI Thread)와 작업자 스레드(Worker Thread)의 제약사항으로 인해 스레드간 데이터 전달이 필요하게 됩니다. 주로 작업자 스레드에서의 결과값을 화면에 나타내기 위한 경우가 많습니다.
2. Thread간 통신방법 (데이터 전달 방법)
1) Message객체 전달 방법 - sendMessage( ) 사용
핸들러의 sendMessage(Message msg) 메소드를 사용하면 Message객체를 전달 할 수 있으며, Message객체는 데이터 전달을 위해 아래와 같은 변수를 이용할 수 있습니다. 또한 받는쪽에서는 handleMessage(Message msg) 메소드를 통해 Message객체를 수신할 수 있습니다.
- int what : Message에 대한 식별 코드용 변수
- int arg1 : 정수값 저장 변수
- int arg2 : 정수값 저장 변수
- Object obj : 객체를 저장할 수 있는 변수
- Messenger replyTo : 이 Message에 대해 답장을 보낼수 있는 Messenger
- int sendingUid : Message를 보낸 uid를 나타내는 필드
2) Runnable 객체 전달 방법 - post( ) 사용
핸들러 또는 뷰 객체의 post(Runnable r) 메소드를 사용하면 Runnable 객체를 전달 할 수 있습니다.
3) Runnable 객체 전달 방법 - runOnUiThread( ) 사용
Activity의 runOnUiThread(Runnable action) 메소드를 사용하게 되면 핸들러 없이도 Runnable 객체를 전달 할 수 있습니다.
메인스레드에서는 기본적으로 루퍼(Looper)가 돌고 있으므로, 작업자 스레드(Worker Thread)에서 UI 작업을 메인스레드에 요청하기 위해서는 메인스레드의 핸들러(Handler)를 이용하면 됩니다.
cf) Thread에서의 Handler, Looper, MessageQueue에 대한 내용은 아래 글을 참고하세요
2023.03.05 - [IT 개발/Android] - [안드로이드] Thread 개념 및 종류와 Handler, Looper, MessageQueue
3. Thread간 통신 예제
1) Message객체 전달 방법 - sendMessage( ) 사용
- MainActivity.java
public class MainActivity extends AppCompatActivity {
TextView textView;
Handler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView);
mHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
switch (msg.what) {
case 0:
textView.setText(msg.arg1 + "");
break;
}
}
};
Thread t = new Thread(new Runnable() {
@Override
public void run() {
for (int i=0; i<100; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Message msg = Message.obtain();
msg.what = 0;
msg.arg1 = i;
mHandler.sendMessage(msg);
}
}
});
t.start();
}
}
- activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textSize="64dp"
android:textColor="@color/purple_700"/>
</LinearLayout>
- 실행결과
2) Runnable 객체 전달 방법 - post( ) 사용
- MainActivity.java
public class MainActivity extends AppCompatActivity {
TextView textView;
Handler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView);
mHandler = new Handler(Looper.getMainLooper());
Thread t = new Thread(new Runnable() {
@Override
public void run() {
for (int i=0; i<100; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
int finalI = i;
mHandler.post(new Runnable() {
@Override
public void run() {
textView.setText(finalI+"");
}
});
}
}
});
t.start();
}
}
cf) 핸들러 대신 뷰의 post( )메소드를 사용하려면 mHandler.post(...); 대신 textView.post(...);로 변경해 주시면 됩니다.
- activity_main.xml : 위와 동일
- 실행결과 : 위와 동일
3) Runnable 객체 전달 방법 - runOnUiThread( ) 사용
- MainActivity.java
public class MainActivity extends AppCompatActivity {
TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView);
Thread t = new Thread(new Runnable() {
@Override
public void run() {
for (int i=0; i<100; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
int finalI = i;
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText(finalI + "");
}
});
}
}
});
t.start();
}
}
- activity_main.xml : 위와 동일
- 실행결과 : 위와 동일
'IT 개발 > Android' 카테고리의 다른 글
[안드로이드] ViewPager2 사용법과 TabLayout 적용 예제 (0) | 2023.03.10 |
---|---|
[안드로이드] Room 사용방법 및 예제 + LiveData적용 (0) | 2023.03.09 |
[안드로이드] Thread 개념 및 종류와 Handler, Looper, MessageQueue (0) | 2023.03.05 |
[안드로이드] CardView 사용법 및 속성 (0) | 2023.02.28 |
[안드로이드] DatePickerDialog 사용법 및 Theme 옵션 (Spinner, Calendar 날짜선택) (0) | 2023.02.21 |