Development/Android

24. Multi Thread -2

궁선이 2018. 5. 5. 01:50

1에 이어서 포스팅 하겠습니다.

AsyncTask는 스레드를 사용하는 매우 편리한 방법입니다.
방법을 외우기만 한다면 매우 편리하죠.
개인의 취향이긴 하지만 저는 AsyncTask를 더욱 선호합니다.

AsyncTask의 특징으로는
1. 백그라운드 작업을 쉽고 간단하게 할 수 있다.
2. 결과를 UI 스레드에서 하는 메소드가 있으므로 UI 스레드에 쉽게 접근
3. 메모리 누수(leak) 현상이 일어나지 않도록 액티비티가 종료될 때 cancel해주어야 함
4. 화면전환시 AsyncTask의 처리를 해주지 않기 때문에 예외현상이나 leak이 나타날 수 있다.

Main Thread
AsyncTask의 구조
Sub Thread
onPreExecute()
doInBackground()
onProgressUpdate()
onPostExecute()

AsyncTask의 메서드
onPreExecute()
(UI Thread)
- AsyncTask execuute 메서도 실행 시 처음 실행되는 메서드
- 백그라운드 작업 전 초기화 할 때 사용
Result doInBackground(Params...)
- 백그라운드 스레드에서 처리된다.
- Execute 메소드 호출 시 전달한 인자들을 params으로 받게된다.
- 진행 중 UI작업이 필요한 경우  publishProgress 함수를 호출하면 UI 작업을 하는 onProgressUpdate가 호출된다.
onProgressUpdate(Progress...)
(UI Thread)
- doInBackground 에서 publish를 호출하며 자동으로 UI스레드에서 실행됨
- publishProgress메소드에서 인자로 전달한 값들을 파라미터로 받아 작업
onPostExecute(Result)
(UI Thread)
- doInBackground 메소드 종료 후 호출
- doInBackground 메소드의 리턴값을 파라미터로 전달
onCancelled()
- doInBackground 메소드에서 작업이 취소되면 onPostExecute 대신 호출됨
AsyncTask 주의 사항
1. AsyncTask 작성법

- 메인 스레드에서 생성하고 호출해야 한다.
- 생성 후 실행은 단 한번만 가능함.
- Execute()와  cancel 함수만 호출 가능함

2. AsyncTask 실행 취소

- doInBackground에서 백그라운드 작업을 처리 하는 중 cancel 메소드에 의해 취소될 수 있음.
- 취소가 되면 isCancelled메소드가 true를 반환하여 doOnBackground실행 후 onPostExecute대신에 onCancelled가 호출 됨.
- 사용자가 취소 버튼을 누를 때 바로 반영이 되게 하기 위해 isCancelled()메소드의 리턴값을 체크해야한다.

AsyncTask 생성하기

AsyncTask에서 작업이 진행되면서 진행단계사이에 인자가 전달되는 경로를
유의깊게 볼 필요가 있습니다.
AsyncTask<A,B,C> 
*A,B,C는 데이터 타입의 wrapper클래스
A : doInBackground의 인자입니다.
B: onProgressUpdate의 인자입니다.
C : onPostExcute의 인자이면서 doInBackground의 반환형입니다.

초기에 A,B,C를 설정해주고 override를 하면 자동으로 적용이 됩니다.

class MyTask extends AsyncTask<Integer,Integer,Void>{ @Override protected void onPreExecute() { } @Override protected Void doInBackground(Integer... params) { //publishProgress(Integer); onProgressUpdate 호출 //params[0], params[1] 같은 방법으로 인자 사용 가능 } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); //values[0], values[1] 같은 방법으로 인자 사용 가능 } @Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); } @Override protected void onCancelled() { super.onCancelled(); } } //실행 MyTask myTask = new MyTask(); myTask.execute();