ANDROID/Android 앱 프로그래밍

[Android] AsyncTask 사용하기

주 녕 2021. 6. 23. 14:34
반응형

모든 내용은 Do it! 안드로이드 앱 프로그래밍을 바탕으로 정리한 것입니다. 

 

기존에 사용했던 핸들러는 코드가 복잡함 && 코드가 순서없이 이곳저곳에서 실행되는 느낌

→ 핸들러(Handler)를 사용하지 않고 좀 더 간단하게 하는 방법 : AsyncTask 

 

AsyncTask

AsyncTask 클래스를 상속받아 새로운 클래스를 만들면 그 안에 스레드를 위한 코드와 UI 접근 코드를 한번에 넣을 수 있음

→ 스레드로 처리해야 하는 코드를 하나의 AsyncTask 클래스로 정의할 수 있다는 장점!

AsyncTask 클래스를 상속하여 새로운 클래스를 정의하면 그 내부에서 필요한 경우마다 콜백 메서드들이 자동으로 호출됨.

아래의 설명과 같이 AsyncTask 클래스를 사용하면 UI 객체에 접근할 수 있기 때문에 하나의 클래스 안에 스레드에서 동작해야 하는 작업과 그 작업의 결과를 UI에 반영하는 코드를 같이 구현할 수 있음.

→ 스레드로 수행해야 할 어떤 기능을 하나의 클래스 만으로 만들 수 있음

 

[ 새로운 스레드에서 동작하는 메서드 ]

  • doInBackground() 메서드
    • 새로 만들어진 스레드에서 백그라운드 작업을 수행함
    • execute() 메서드를 호출할 때 사용된 파라미터를 배열로 전달받음

[ 메인 스레드에서 동작하는 메서드 ]

  • onPreExecute() 메서드
    • 백그라운드 작업을 수행하기 전에 호출됨
    • 메인 스레드에서 초기화 작업에 사용됨
  • onProgressUpdate() 메서드
    • 백그라운드 작업의 진행 상태를 표시하기 위해 호출됨
    • 작업 수행 중간 중간에 UI 객체에 접근하는 경우에 사용됨
    • 이 메서드가 호출되려면 백그라운드 작업 중간에 publishProgress() 메서드를 호출해야 함
  • onPostExecute() 메서드
    • 백그라운드 작업이 끝난 후에 호출됨
    • 메인 스레드에서 실행되며 메모리 리소스를 해제하는 등의 작업에 사용됨
    • 백그라운드 작업의 결과는 Result 타입의 파라미터로 전달됨

[ 그 외의 메서드 ]

  • execute() 메서드
    • 정의된 백그라운드 작업을 수행하고 필요 시 결과를 메인 스레드에서 실행하는 메서드
  • cancel() 메서드
    • 작업을 취소하는 메서드
    • 이 메서드로 작업을 취소했을 때, onCancelled() 메서드가 호출됨
  • getStatus() 메서드
    • 작업의 진행 상황을 확인하고 싶을 때 사용하는 메서드
    • PENDING(시작 전), RUNNING(실행 중), FINISHED(종료) 상태로 구분됨

 

[예제]

public class AsyncActivity extends AppCompatActivity {

    BackgroundTask task;
    int value;

    ProgressBar progressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_async);

        progressBar = findViewById(R.id.async_progress);

        Button executeButton = findViewById(R.id.async_execute_btn);
        executeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 태스크 객체 만들어 실행시키기
                task = new BackgroundTask();
                task.execute();
            }
        });

        Button stopButton = findViewById(R.id.async_stop_btn);
        stopButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                task.cancel(true);
            }
        });
    }

    class BackgroundTask extends AsyncTask<Integer, Integer, Integer> {
        // <> 안의 자료형은 재정의할 새로운 클래스의 메서드가 어떤 자료형의 파라미터를 갖는지 알려줌

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            value = 0;
            progressBar.setProgress(value);
        }

        @Override
        protected Integer doInBackground(Integer... integers) {
            while (isCancelled() == false) {
                value++;
                if (value >= 100) {
                    break;
                } else {
                    // 중간 중간 진행상태를 업데이트하기 위해 호출
                    publishProgress(value);
                }

                try {
                    Thread.sleep(100);
                } catch (InterruptedException ex) {}
            }

            return value;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            progressBar.setProgress(values[0].intValue());
        }

        @Override
        protected void onPostExecute(Integer integer) {
            super.onPostExecute(integer);
            progressBar.setProgress(0);
        }

        @Override
        protected void onCancelled() {
            super.onCancelled();
            progressBar.setProgress(0);
        }
    }
}
  • AsyncTask 클래스를 상속하는 코드를 보면 < > 사이에 자료형들이 정의되어 있음
    • 이 클래스를 상속하면서 재정의할 새로운 클래스의 메서드가 어떤 자료형의 파라미터를 가질 것인지를 알려주는 역할
    • < > 안에 명시한 자료형은 순서에 따라 doInBackgorund()의 파라미터, onProgressUpdate()의 파라미터, onPostExecute()의 파라미터를 결정함
    • onPreExecute() 메서드는 초기화 단계에서 사용되므로 값을 저장하기 위해 value 변수의 값과 프로그래스바의 값을 초기화함
  • doInBackground() 메서드는 주된 작업을 실행하는데 사용됨
    • 중간 중간 진행상태를 UI에 업데이트하도록 만들기 위해 publishProgress() 메서드를 호출함
    • onProgressUpdate() 메서드는 doInBackground()에서 publishProgress() 메서드가 호출될 때마다 자동으로 호출됨

 

 

반응형