IT/Android

안드로이드에서 AsyncTask를 활용한 스레드 동작

김효랑이 2018. 12. 7. 11:02
728x90
반응형

 호야의 블로그 

[안드로이드] 안드로이드에서 AsyncTask를 활용한 스레드 동작

안드로이드 스튜디오에서 프로그레스 바를 생성하는 방법을 알려드리겠습니다. 프로그레스 바는 다운로드 상황을 눈으로 볼 수 있는 HORIZONTAL 스타일이 있고, 시계 바늘처럼 회전하여 로딩 중을 알려주는 스타일 SPIINER가 있습니다. 
저는 AsyncTask를 활용하여 스레드 반복 작업에 사용하였습니다. AsyncTask는 스레드 기술 중 하나로 메인 스레드 대신 특정 반복 작업을 수행 동작합니다. 
하지만 AsyncTask의 단점이 있는데 스레드가 동작 중일 때 UI 컨트롤을 할 수 없다는 점입니다. 안드로이드에서는 몇 초동안 동작이 감지되지 않으면 '대기', '중지' 같은 메시지가 뜨며 프로그램이 멈추고, 스레드 동작이 끝나야 정상으로 사용이 가능합니다. 따라서 이러한 무한 대기 상태에 걸리지 않으려면 프로그레스 바를 활용하면 됩니다. 보조 스레드가 동작 중일 때 프로그레스 바를 보여주어 스레드의 작업 현황을 확인 할 수 있습니다.

안드로이드 스튜디오 로고

AsyncTask

AsyncTask는 생명주기가 정해져 있는데 주기는 아래와 같습니다. 아래와 같은 생명주기에 맞춰서 코드를 작성하시면 됩니다. 굳이 다 사용하지 않아도 됩니다.


onPreExecute() - 백그라운드 실행 이전에 동작

doInBackground(params) - 백그라운드에 호출된 데이터 params로 본격적인 스레드 동작을 수행

onProgressUpdate(Progress) - 작업의 진행 상황을 보고

onPostExecute(Result) - 수행 종료 후 결과 반환

onCancelled(Result) - 사용자가 특정 조건에서 발동시키면 스레드가 작업을 중단


onPreExecute() -> doInBackground(params) -> onProgressUpdate(Progress) -> onPostExecute(Result) -> onCancelled(Result)


구현

액티비티에서는 AsyncTask를 다음과 같이 호출할 수 있습니다. 먼저 액티비티 내에 다음과 같이 클래스를 선언합니다. 가장 기본적인 구성입니다.

//액티비티 MainActivity.java

test cr = new test(); //test는 AsyncTask를 정의한 클래스 네임입니다. cr은 해당하는 변수 명입니다. String result; //스레드 결과값을 넣을 변수 정의 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.MainActivity); String params0 = null; //스레드에 넣을 파라미터 정의 String params1 = null; String params2 = null; String params3 = null; AsyncTask<String, String, String> at = cr.execute(params0, params1, params2, params3); //AyncTask 동작 try { result = at.get(); //결과 값 가져오기 } catch (Exception e) { e.printStackTrace(); } }



그리고 AsyncTask가 정의된 클래스로 이동해서 다음과 같이 추가로 정의합니다. 이는 현재 액티비티가 진행중인 컨텍스트를 지정하기 위해서 입니다.

//test.java - AsyncTask 동작 클래스 내에 선언

public test(Context ctx){ mctx = ctx; }


다음으로 onPreExecute()를 정의합니다. 이는 AsyncTask가 백그라운드에서 동작하기 이전에 실행되는 부분입니다.

//test.java - AsyncTask 동작 클래스 내에 선언

@Override protected void onPreExecute() { pdialog = new ProgressDialog(mctx); //프로그래스 다이얼로그 정의 pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); //프로그래스 다이얼로그 바 스타일로 정의 pdialog.setMessage("콘텐츠 확인 중 입니다..."); //바의 메시지 출력 pdialog.show(); //다이얼로그 출력 super.onPreExecute(); }


다음은 doinBackground로 실제 스레드가 동작하는 파트입니다. params는 액티비티에서 AsyncTask를 호출할 때 넣는 파라미터로 스레드에서 호출하여 사용할 수 있습니다. 

//test.java - AsyncTask 동작 클래스

protected String doInBackground(String... params) { String Result; status = (Integer) params[0]; //파라미터의 [0]번째 값을 status 변수에 넣습니다. for(int i=0;i<50;i++) { //50번 반복하는 반복 스레드입니다. pdialog.setProgress(i * 2); //한 루프 동작 시 프로그레스 바가 2씩 증가하여 50번 동작 시 100까지 차게 됩니다. try { Log.e("log", "test: " + (status+i)); } catch (Exception e) { Log.e("log error Result", "Error: " + e.getMessage()); } }return Result; //루프 종료 시 리턴합니다. }


마지막으로 onPostExecute는 백그라운드 동작 종료 시 실행되며 스레드 종료를 위한 함수입니다.

//test.java - AsyncTask 동작 클래스 내에 선언

@Override protected void onPostExecute(ArrayList s) { super.onPostExecute(s); pdialog.dismiss(); //백그라운드 동작 종료 시 실행되며 다이얼로그를 종료하고 액티비티로 빠져나옵니다. }


아래는 AsyncTask 클래스의 전체 코드입니다.

public class test extends AsyncTask<String, String, String> { private ProgressDialog pdialog; private Context mctx; private int status; String Result; public CallRemote_Item(Context ctx){ mctx = ctx; } @Override protected void onPreExecute() { pdialog = new ProgressDialog(mctx); pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); pdialog.setMessage("콘텐츠 확인 중 입니다..."); // show dialog pdialog.show(); super.onPreExecute(); } protected String doInBackground(String... params) { status = (Integer) params[0]; for(int i=0;i<50;i++) { pdialog.setProgress(i * 2); try { Log.e("log", "test: " + (status+i)); } catch (Exception e) { Log.e("log error Result", "Error: " + e.getMessage()); } }return Result; } @Override protected void onPostExecute(ArrayList s) { super.onPostExecute(s); pdialog.dismiss(); } }


후기 및 정리

직접 실습을 하시며 생명 주기를 이해하시면 많은 도움이 될 것입니다. AsyncTask는 오래 걸리는 연산 작업에는 매우 좋지 못한 선택입니다. 연산이 오래 걸리면 로드 시간이 길어져 어플리케이션 품질이 떨어지기 때문입니다. 오래 걸리는 작업에서는 Thread를 활용하시면 될 것입니다. Thread는 연산 중에도 UI 동작이 가능하여 보다 편리합니다.

다음 글에서는 Thread의 구현 방법을 알려드리겠습니다. 감사합니다.



동원샘물 미네마인,... 제주삼다수, 2L,... 농심 백산수, 2L... 갭 남성용 로고 플...



조금의 도움이 되셨다면 로그인 없이도 가능한 댓글과

왼쪽 아래 ♥공감 버튼을 꾹 눌러주세요! 




728x90
반응형

'IT > Android' 카테고리의 다른 글

cannot resolve symbol ~ 에러 해결하기  (18) 2018.12.21
안드로이드에서 웹서비스 호출하기(wsdl)  (0) 2018.10.26