티스토리 뷰
# 스레드(thread)?
: 동시에 수행이 가능한 작업 단위
: 하나의 프로세스 안에서 동시에 수행되어야 하는 작업을 위해 사용
✔ 같은 프로세스 안에 들어 있으면서 메모리 리소스를 공유 (효율적)
✔ 동시에 리소스에 접근할 때 데드락(DeadLock)이 발생할 수 있음 → 작업을 순서대로 처리하게 도와주는 핸들러로 해결
✔ 안드로이드에서 UI 처리할 때 사용되는 기본 스레드를 '메인 스레드'라고 부름
💡 같은 프로세스 안에서 일련의 기능이 순서대로 실행될 때 대부분 큰 문제가 없지만, 대기 시간이 길어지는 네트워크 요청 등의 기능을 수행할 때는 화면에 보이는 UI도 멈춤 상태로 있게 되는 문제가 발생! → 해결책은 서비스 또는 멀티 스레드!
# 핸들러(Handler)?
: 메시지 큐로 메인 스레드에서 처리할 메시지를 전달하는 역할
💡 안드로이드 앱에서 메인 스레드는 메시지 큐(Message Queue) 수신을 대기하는 루프를 실행하며, 사용자 입력과 시스템 이벤트, 화면 그리기 등의 메시지가 수신되면 각 메시지에 매핑된 핸들러의 메서드를 실행
# 핸들러를 사용해 스레드에서 메인 스레드에 접근하기 위한 과정
1) 핸들러가 관리하는 메시지 큐에서 처리할 수 있는 메시지 객체 참조 (obtainMessage() 메서드 이용)
2) 메시지 객체에 필요한 정보(Bundle객체, Runnable객체)를 넣은 후 메시지 큐에 넣기(sendMessage() 메서드 이용)
3) 메시지 큐에 들어간 메시지는 순서대로 핸들러가 처리(handleMessage()메서드 이용)
💡 handleMessage() 메서드에 들어있는 코드가 수행되는 위치는 메인 스레드!
# 스레드를 구현해보자!
설명) (1)'스레드 시작'버튼을 누르면 (2) 1초마다 value값이 1증가하는 스레드가 시작하고 (3) 변화하는 value값이 액티비티안에 텍스트뷰에 나타남
1) 액티비티 xml 레이아웃 만들기
2) 자바소스 파일에서 스레드 처리
public class MainActivity extends AppCompatActivity {
TextView textView;
Handler handler = new Handler(); //API 기본 핸들러 객체 생성
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
BackgroundThread thread = new BackgroundThread();
thread.start(); // 스레드 시작 -> 자동으로 run() 실행
}
});
}
class BackgroundThread extends Thread {
int value = 0;
public void run() {
for(int i=0; i<100; ++i) {
try{
Thread.sleep(1000); // 1초 sleep
} catch (Exception e) {}
value += 1;
Log.d("Thread", "value : "+value);
// 스레드 안에 스레드가 하는 행동이 있으니까 이해하기 더 편함.
handler.post(new Runnable() { //핸들러가 메시지 큐에 메시지(Runnable객체)를 넣음
@Override
public void run() {
textView.setText("value 값: "+value);
}
});
}
}
}
class MainHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//메시지가 메인 스레드에서 수행될 때 필요한 기능 추가
Bundle bundle = msg.getData();
int value = bundle.getInt("value");
textView.setText("value 값: "+value);
}
}
}
# 핸들러를 구현해보자!
설명) (1)'요청하기' 버튼을 누르면 (2)'요청하겠습니까?'대화 상자 표시, (3)사용자가 '예' 버튼을 누르면 (4)5초뒤에 액티비티의 텍스트뷰가 '요청완료'로 바뀜.
1) 액티비티 xml 레이아웃 만들기
2) 액티비티 자바소스파일에서 핸들러 처리
public class MainActivity extends AppCompatActivity {
TextView textView;
Handler handler = new Handler(); //핸들러 객체 참조
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView);
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
request();
}
});
}
private void request() {
String title = "원격 요청";
String message = "데이터를 요청하시겠습니까?";
String titleButtonYes = "예";
String titleButtonNo = "아니오";
AlertDialog dialog = makeRequestDialog(title, message, titleButtonYes, titleButtonNo); //대화상자 만들기
dialog.show(); //대화상자를 액티비티에 띄움
textView.setText("대화상자 표시중...");
}
private AlertDialog makeRequestDialog(CharSequence title, CharSequence message,
CharSequence titleButtonYes, CharSequence titleButtonNo) {
AlertDialog.Builder requestDialog = new AlertDialog.Builder(this);
requestDialog.setTitle(title);
requestDialog.setMessage(message);
requestDialog.setPositiveButton(titleButtonYes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int i) {
textView.setText("5초 후에 결과 표시됨.");
handler.postDelayed(new Runnable() { //메시지 규에 메시지 넣기
@Override
public void run() {
textView.setText("요청 완료됨.");
}
}, 5000); //5초 딜레이
}
});
requestDialog.setNegativeButton(titleButtonNo, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int i) {}
});
return requestDialog.create();
}
}
출처
Do it! 안드로이드 앱 프로그래밍(개정8판)
'안드로이드 > 자바' 카테고리의 다른 글
[Effective Java] 1. 생성자 대신 정적 팩터리 메서드를 고려하라 (0) | 2023.09.20 |
---|---|
[안드로이드] 네트워킹 (0) | 2021.09.13 |
[안드로이드] 스피너 (0) | 2021.09.09 |
[안드로이드] 리싸이클러뷰 (0) | 2021.09.09 |
[안드로이드] 레이아웃 커스텀 (0) | 2021.09.07 |