[안드로이드 예제] AsyncTask 이용하기 :: 소림사의 홍반장!

[안드로이드 예제] AsyncTask 이용하기

2012. 10. 23. 20:34 - 삘쏘굿

참고 : http://developer.android.com/reference/android/os/AsyncTask.html


AsyncTask
 안드로이드는 UI Thread 에서 일정 시간동안 유저의 반응에 응답하지 못하면 ANR(Application Not Responding) 오류를
 발생시킨다. 하지만 네트워크를 통한 데이터 전송 등 계속적인 작업이 실행되어야 할 경우 AsyncTask를 상속받은
 클래스를 통해서 작업을 수행하는 것으로 ANR 오류를 방지할 수 있다.


 (1) 작성방법
  AsyncTask를 상속받았을 경우 Generics로 3가지 인자값을 지정해주어야 한다.
  AsyncTask<Params, Progress, Result>
  - Params : AsyncTask가 실행시 execute(p1, p2 ...); 메소드를 통해서 넘겨주는 값을 선언
  - Progress : doInBackground 메소드를 통해서 실행되는 publishProgress(p) 메소드의 인자값으로 넘길 값이다.
   또한 오버라이딩한 onProgressUpdate(Progress p) 메소드의 인자값으로 넘겨주게 되는 값이다.
  - Result : doInBackground 메소드를 통해서 리턴되고, onPostExecute(Result r) 메소드의 인자값으로 들어오게 되는 값이다.


 (2) 주요 메소드
  - protected abstract Result doInBackground(Params... params); (필수 구현 메소드)
  - protected void onPostExecute(Result result) 결과값을 가지고 처리하고 싶은 일을 실행하는 메소드
  - protected void onProgressUpdate(Progress... values) 진행중에 해당하는 값을 가지고 처리하고 싶은 일을
   실행하는 메소드(일반적으로 프로그레스바의 값을 증가시키기 위해 사용)


 (3) 실행 순서
  - onPreExecute() -> doInBackground() ->
    publishProgress() 를 통해서 넘어온 값으로 onProgressUpdate()가 실행 -> onPostExecute()


 (4) 사용예제 (안드로이드 AsyncTask JavaDoc에 나온 예제)

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {

      protected Long doInBackground(URL... urls) {

            int count = urls.length;

            long totalSize = 0;

            for (int i = 0; i < count; i++) {

                  totalSize += Downloader.downloadFile(urls[i]);

                  publishProgress((int) ((i / (float) count) * 100));

            }

            return totalSize;

      }

 

      protected void onProgressUpdate(Integer... progress) {

            setProgressPercent(progress[0]);

      }

 

      protected void onPostExecute(Long result) {

            showDialog("Downloaded " + result + " bytes");

      }

}

 

 

실 사용예제 - xmlParser와 같이 사용

package com.example.netapp;

 

import java.io.*;

import java.util.*;

 

import org.apache.http.*;

import org.apache.http.client.entity.*;

import org.apache.http.client.methods.*;

import org.apache.http.impl.client.*;

import org.apache.http.message.*;

import org.apache.http.params.*;

import org.xmlpull.v1.*;

 

import android.app.*;

import android.os.*;

import android.util.*;

import android.widget.*;

 

public class BoardActivity extends ListActivity {

     

      private ProgressDialog dialog;

      protected ArrayList<Map<String, String>> dataList;

 

      private AsyncTask<Void, Integer, Void> mTask = new AsyncTask<Void, Integer, Void>() {

           

 

            protected Void doInBackground(Void... p) {

                 

                  // 새롭게 데이터를 가져오는 부분(기존 List 삭제)

                  dataList = new ArrayList<Map<String,String>>();

                 

                 

                  try {

                        publishProgress(1);        // 접속 중

                        // 5초가 지나면 타임아웃 시킨다. 설정하지 않으면 계속 기다림

                        HttpParams params = new BasicHttpParams();

                        HttpConnectionParams.setConnectionTimeout(params, 10000);

 

                        DefaultHttpClient client = new DefaultHttpClient(params);

                        // POST 방식으로 요청을 보내기 위해 요청주소를 인자값으로 객체 생성

                        HttpPost request =

//                           new HttpPost("http://14.37.37.161:8080/main2.xml");

                                   new HttpPost("http://14.37.37.166:8080/sp/re/xml");

                        ArrayList<BasicNameValuePair> parameters =

                                               new ArrayList<BasicNameValuePair>();

 

                        // 인자값을 ArrayList로 저장

                        parameters.add(new BasicNameValuePair("id", "완쌤"));

                       

                        // 요청 객체(HttpPost)에 파라미터를 인코딩해서 저장

                        request.setEntity(

                                   new UrlEncodedFormEntity(parameters, "UTF-8"));

                       

                       

                        publishProgress(2);        // 데이터 수신 중

                        // 요청을 실행해서 응답을 받는다.

                        HttpResponse response = client.execute(request);

                        InputStream is = response.getEntity().getContent();

                       

                       

                       

                       

                        // XMLPullParser 이용 파싱

                        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();

                        XmlPullParser parser = factory.newPullParser();

                        parser.setInput(is, "UTF-8");

                       

                       

                        publishProgress(3);        // 데이터 분석중

                        int event = XmlPullParser.START_DOCUMENT;

                        while((event = parser.next())!=XmlPullParser.END_DOCUMENT) {

                             switch(event) {

                             case XmlPullParser.START_TAG:

                                   // item 태그가 아니면 건너뛴다.

                                   if(!parser.getName().equals("item"))

                                         break;

                                   String title = parser.getAttributeValue(null, "title");

                                  String wdate= parser.getAttributeValue(null, "wdate");

                                   HashMap<String, String> map = new HashMap<String, String>();

                                   map.put("title",title);

                                   map.put("wdate",wdate);

                                   dataList.add(map);

                                  

                             }

                        }

                       

                       

                       

                  } catch (Exception e) {

                        publishProgress(-1);

                        Log.e("net","게시판 오류",e);

                  }

                 

                 

                  return null;

                 

            }

           

            protected void onProgressUpdate(Integer[] values) {

                  switch(values[0]) {

                  case -1:

                        Toast.makeText(getApplicationContext(), "통신 오류", 0).show();

                        break;

                  case 1:

                        dialog.setMessage("접속 중...");

                        break;

                  case 2:

                        dialog.setMessage("데이터 수신 중...");

                        break;

                  case 3:

                        dialog.setMessage("데이터 분석 중...");

                        break;

                  }

                  dialog.setProgress(values[0]);

            }

           

            protected void onPostExecute(Void result) {

                  SimpleAdapter adapter = new SimpleAdapter(

                             getApplicationContext(), dataList,

                             android.R.layout.simple_list_item_2,

                             new String[]{"title","wdate"},

                             new int[]{android.R.id.text1,android.R.id.text2});

                  setListAdapter(adapter);

                 

                  dialog.dismiss();

                  Toast.makeText(getApplicationContext(), "로딩완료", 0).show();

            }

           

      };

     

      @Override

      protected void onCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);

            setContentView(R.layout.activity_list);

            // ProgressDialog 띄워서 1~100까지 게이지를 채우고 사라질 것.

            dialog = new ProgressDialog(this);

            dialog.setTitle("Loading...");

            dialog.setMessage("접속 시작");

            dialog.setCancelable(false);

            dialog.setMax(3);

            dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

            dialog.show();

           

            mTask.execute();

      }

     

}

 

다른 카테고리의 글 목록

Dev. 안드로이드/참고소스 카테고리의 포스트를 톺아봅니다