-
ThreadAndroid/AndroidStudio 2018. 7. 1. 00:37
안드로이드 시스템은 어플이 실행되면 메인스레드가 실행되게 되어있다.
메인스레드에 너무 많은 작업을 진행하게되면 성능 저하가 발행하므로 부하가 많은 작업은 다른 스레드에서 실행하는 것이좋다.
(스레드는 표준자바와 같다)
안드로이드 UI는 메인스레드에서만 접근할 수 있다(싱글스레드라고 칭한다)
여러 스레드에서 동시에 같은 뷰에 접근하게 될경우 충될이 발생하기 때문에 이를 방지하기 위해서이다.
handler, looper등의 방법이 있다.
Looper와 Handler의 작동원리
메인 스레드는 내부적으로 looper를 가지고 있고 루퍼는 메세지 큐를 가지고 있다.
메세지 큐는 다른 스레드로 부터 전달받은 메세지나 Runnable 객체를 가지고 있으며 차레로 꺼내어 Handler로 보내 Handler가 처리할 수 있도록 한다.
Handler는 메세지를 처리하거나, 혹은 다른 스레드로부터 받은 메세지를 Looper로 보내는 역할 을 한다.
Handler
핸들러 객체를 생성하면 생성한 스레드에 종속된다. 메세지 큐로부터 message나 runnable 객체를 처리하거나 받아 스레드 간의 통신을 돕는다.
Looper
Looper는 무한 루프를 돌면서 Message Queue에 들어온 객체를 차례로 꺼내 Handler에 전달하는 역할을 한다.
메인스레드는 Looper을 기본적으로 가지고 있고 새로 생성한 스레드는 그렇지않아 메세지를 받을 수 없다.
새로 생성된 스레드는 prepare() 메서드를 통해서 Looper를 생성하고 loop() 메소드를 통해서 무한루프를 돌 수 있도록한다.
quit()나 quitsafely()메서드를 통해 loop를 중단할 수 있다.
Message와 Runnable
Message는 스레드간 통신할 내용을 담은 객체이다.
Message가 필요한 경우에 객체를 생성하면 성능 이슈가 발생할 수 있으므로 안드로이드 시스템에 만들어둔 Message Pool의 객체를 재사용한다.
obtain() 메서드는 빈 Message 객체를 리턴한다.
Message는 int나 object같이 스레드간 통신할 내용을 담는다면 Runnable은 실행할 run()메서드와 그 내부에서 실행될 코드를 담는다.
HandlerThread
안드로이드의 스레드는 자바의 스레드를 사용했기 때문에 Looper를 기본으로 가지고 있지 않는다. 이를 개선하기위해 Looper를 자동으로 보유한 HandlerThread를 제공한다.
AsyncTask
스레드나 메시지 루프 등의 작동 원리를 몰라도 하나의 클래스에 UI작업과 background 작업을 쉽게 할 수 있도록 안드로이드에서 제공하는 클래스.
AsnycTask<>를 상속받은 클래스를 정의합니다.
doInBackground() 메소드를 재정의 합니다. - 스레드에서 일어나는 일들
doInBackground() 안에서 publishProgress()메소드를 호출하면 Ui에 접근가능한 onProgressUpdate()가 실행됩니다.
onProgressUdapte() 메소드를 재정의하여 ui에 접근합니다.
doInbackground()메소드가 return 값을 전달하면 onPostExecute() 메소드가 실행됩니다.
onPostExecute() 또한 스레드가 끝날때 ui에 접근이 가능합니다.
class ProgressTask extends AsyncTask<String, Integer, Integer> {
int value =0;
@Override
protected Integer doInBackground(String... strings) {
while(true){
if(value > 100){
break;
}
value += 1;
publishProgress(value); // onProgressUpdate()
try{
Thread.sleep(200);
}catch(Exception e){}
}
return value;
}
@Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
Toast.makeText(getApplicationContext(), "완료됨", Toast.LENGTH_LONG).show();
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
progressBar.setProgress(values[0].intValue());
}
}asyncTask를 사용하여 progressbar의 값을 변경하는 예제
* https://academy.realm.io/kr/posts/android-thread-looper-handler/ 내용을 참고하여 정리하였습니다.
* https://www.edwith.org/boostcourse-android/lecture/17087/ 를 참고하여 asyncTask를 정리하였습니다.
'Android > AndroidStudio' 카테고리의 다른 글
안드로이드 thread와 handler (0) 2018.07.07 Android Guideline (0) 2018.07.02 Guide to background processing (0) 2018.06.30 Fragment (0) 2018.06.21 서비스로 명령 전달 (1) 2018.06.20