ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ANR 을 방지 하기 위한 AsyncTask
    안드로이드/학습&강좌 2011. 5. 15. 14:18

    안드로이드의 기본을 생각하자면 안드로이드 OS 자체는 모바일용이다. PC용이 아니다 라는것은 그만큼 CPU의 성능이 아직은
     
    pc 에 못 미칠뿐더러, 메모리의 양도 한참 적다. 물론예전의 2g 2.5g의 상황에 비하자면.. 말도 안되게 좋아진 상황이다.

    당시에 기준이 되는건 kb byte 단위로 리소스를 줄이려 부단히도 노력했지만 지금은 그런 제약이 많이 적다. mByte 단위로
     
    어플의 용량이 늘어나도 버텨주니깐 많이 자유로운 편이지만, 기본은 PC가 아니고 핸드폰이라는걸 명심해야 한다. (물론 태블
    릿 PC도 있지만;;)

    안드로이드 핸드폰에서 시간이 오래 걸리는 작업 예를 들자면 서버에 접속해서 데이터를 받는 경우 무한정 응답을 기다리고 있

    일 수 없기때문에 약 5초정도 응답이 없는 경우 안드로이드 OS 에서 스스로 강제 종료 시켜 버린다. 그렇기 때문에 서버와 통신

    하는 부분또는 응답시간을 예측하기 어려운 경우에는 Thread 를 이용해서 작업을 해줘야 한다.

    Runable 을 이용해서 Thread를 구현해도 되겟지만 안드로이드에서 편리하게 AsyncTask 라는 클래스를 제공하고 있다.

    이 클래스를 앞서 이야기 했던 작업들을 편히 Thread를 이용해 구현할 수 있다.

    이번에 구현해 볼 예제는 무엇인가의 계산이 있다 가정하고 그 계산이 10초이상 걸린다 생각하자,

    기본적으로 Thread를 이용하지 않는다면 강제 종료될 구조라 생각해 줬으면 한다.

      private int sum(){
         for (int i = 0; i < 1000000; i++) {
       sum += i;
      }
         return sum;
        }

    이 간단한 함수를 Background 에서 돌린다 생각하고, 10초 정도 sleep을 주겠다.

    실행 화면을 보자면

     



    이런식이다. 앞에 -가 붙은것은 int의 범위를 넘어 섰을 것이기 때문이므로 long 이나 double을로 선언하면 잘 나올 것이다.

    간단하게 예제를 살펴 보자

    package com.tistory.ememomo;

    import android.app.Activity;
    import android.app.ProgressDialog;
    import android.content.Context;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.widget.EditText;
    import android.widget.TextView;
    import android.widget.Toast;

    public class StudyAndroid extends Activity {
        /** Called when the activity is first created. */
     TextView txtSum;
     EditText edtSum;
     int sum, total;
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
           
            txtSum = (TextView)findViewById(R.id.txt_sum);
            edtSum = (EditText)findViewById(R.id.edt_sum);
            asyncCalcSum();
           
        }
       
        private int sum(){
         for (int i = 0; i < 1000000; i++) {
       sum += i;
      }
         return sum;
        }
       
        private void asyncCalcSum() {
      new AsyncTask<Void, Void, Void>() {
       private ProgressDialog mProgressDialog;
       protected void onPreExecute() {
        //미리 준비해줘야 하는 작업
        mProgressDialog = showLoadingDialog(StudyAndroid.this, false);
        
       };
       @Override
       protected Void doInBackground(Void... params) {
        //백그라운드에서 실행되는 작업
        try {
         Thread.sleep(10000);
        } catch (InterruptedException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
        }
        total = sum();
        return null;
       }
       
       @Override
       protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        //백그라운드 작업이 끝난후 해줄 작업
        mProgressDialog.dismiss();
        Toast.makeText(StudyAndroid.this, "계산 완료" + total, Toast.LENGTH_SHORT).show();
        txtSum.setText(String.valueOf(total));
        edtSum.setText(String.valueOf(total));
       }
      }.execute();
     }
       
        public ProgressDialog showLoadingDialog(Context context, boolean cancelable) {
            ProgressDialog dialog = new ProgressDialog(context);
            dialog.setMessage("계산 중입니다....");
            dialog.setIndeterminate(true);
            dialog.setCancelable(cancelable);
            dialog.show();
            return dialog;
        }
    }



    빨간 줄을 자세히 보기 바란다. 한번 돌려 보고 나면 이해가 잘 될 것이기 때문에 소스를 첨부한다.

    댓글 1

    • 프로필사진

      죄송하지만 저도좀 보내주시면 안될까요 ㅠㅠ
      안드로이드에서 서버로 이미지를 전송해서 db에 저장하는것을 하려고 하는데
      2주동안 고민해도 안되네요 ㅠㅠ 제발 부탁드립니다.
      alsehdghks2@naver.com ㅠㅠ 소스좀 보내주시면 안될까요

      2012.05.29 21:59
COPYRIGHT 2010 EpoNg. ALL RIGHTS RESERVED.