Tag Archives: 백그라운드

[Java/Android] AsyncTask를 사용하여 특정 작업 수행하기

기존에 글 [Thread를 이용한 특정 작업 수행하기]에서는 쓰레드를 이용하여 백그라운드에서 다른 작업을 수행하는 방법에 대해 설명을 하였습니다. 하지만 이방법은 안드로이드에서는 UI에 접근할 수 없는등 몇가지 예상치 못한 문제를 만날 수 있습니다.

이경우 AsyncTask를 사용하시면 이러한 문제를 해결할 수 있습니다. 간단하게 만들어본 예제를 보여드리겠습니다.

private Button mButton;
private ProgressBar mProgress;
private AsyncTask<Void, Integer, Void> mTask;

@Override
public void onCreate(Bundle savedInstanceState)
{
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  mButton = (Button) findViewById(R.id.button);
  mProgress = (ProgressBar) findViewById(R.id.progress);

  mButton.setOnClickListener(this);
}

@Override
public void onClick(View v)
{
  // 시작 버튼
  if(mButton.getText().equals("start"))
  {
    // AsyncTask는 재활용할 수 없습니다. 매번 새롭게 생성
    mTask = new AsyncTask<Void, Integer, Void>()
    {
      // 작업 취소시 사용하기 위한 플래그
      private boolean isCanceled = false;

      // 작업을 시작하기 직전에 호출되는 메서드
      @Override
      protected void onPreExecute()
      {
        publishProgress(0);
        isCanceled = false;
      }

      // 백그라운드에서 작업
      @Override
      protected Void doInBackground(Void... params)
      {
        // 0.1초마다 100단계로 구성된 프로그래스바를 1씩 증가시킵니다.
        for(int i = 1 ; i <= 100 && ! isCanceled ; i++)
        {
          try
          {
            publishProgress(i);
            Thread.sleep(100);
          }
          catch(InterruptedException e)
          {
            e.printStackTrace();
          }
        }

        return null;
      }

      // publishProgress() 메서드를 통해 호출됩니다. 진행사항을 표시하는데에 쓰입니다.
      @Override
      protected void onProgressUpdate(Integer... progress)
      {
        mProgress.setProgress(progress[0]);
      }

      // 작업 완료 직후에 호출되는 메소드
      @Override
      protected void onPostExecute(Void result)
      {
        Toast.makeText(AsyncTaskExampleActivity.this, "완료됨", Toast.LENGTH_SHORT).show();
        mButton.setText("start");
      }

      // 외부에서 강제로 취소할때 호출되는 메소드
      @Override
      protected void onCancelled()
      {
        isCanceled = true;
        publishProgress(0);
        Toast.makeText(AsyncTaskExampleActivity.this, "취소됨", Toast.LENGTH_SHORT).show();
      }
    };

    // 작업 시작
    mTask.execute();
    mButton.setText("cancel");
  }
  // 취소 버튼
  else if(mButton.getText().equals("cancel"))
  {
    mTask.cancel(false);
    mButton.setText("start");
  }
}

위에서 관심있게 이야기 해볼것은 new AsyncTask를 선언할때에 나오는 3개의 Generic 인자입니다.

첫번째 인자execute()시에 넘겨 받을 인자를 정의합니다. doInBackground()에서 호출될때 값이 넘어가게 되며 여러개의 값을 넘겨받을 수 있도록 되어있습니다. 다수의 값을 처리하도록 할 수 있습니다.

두번째 인자onProgressUpdate()가 호출될때 넘겨받을 인자를 뜻합니다. 마찬가지로 publishProgress()를 통해 넘겨줄 인자이기도 합니다. 마찬가지로 다수의 인자를 넘겨받을수도 있으며 위의 예제에서는 단순히 ProgressBar를 증가시키는것밖에 안하기 때문에 1개의 Integer형만을 받도록 하였습니다.

세번째 인자onPostExecute()가 호출될때 넘겨받을 인자를 뜻합니다. 작업이 끝날때 어떤작업이 끝났는지를 알려주고 싶다거나 하면 그 작업 이름을 넘겨주면 되겠죠. 이와 같이 작업이 끝났을때 무언가 처리를 하고 싶은데 이것을 작업 수행 시점에 넘겨주고 싶다면 이 세번째 인자를 사용하시면 됩니다.

사용자 삽입 이미지[샘플코드 다운로드]

[Java/Android] 현재 실행중인 어플리케이션을 백그라운드로 전환하기

현재 실행중인 어플리케이션을 백그라운드로 전화하기 위해서(다른 말로는 즉시 홈스크린을 띄우기 위해서)는 두가지 방법을 사용할 수 있습니다. moveTaskToBack라는 메서드를 사용하거나 Intent를 이용하여 홈을 띄우는 방법이 있습니다.

1. 메서드 활용하기

Activity에서 호출이 가능한 moveTaskToBack(boolean nonRoot)라는 메서드는 인자로 boolean형을 받고 결과값을 boolean형으로 반환합니다. 이 메서드는 현재의 엑티비티가 속해있는 테스크를 백그라운드로 즉시 이동시킵니다. 정상적으로 이동이 되었다면 true가 반환이 되며 이동에 실패할 경우 false가 반환됩니다.

하나의 인자를 받는데 true를 입력할 경우 어떠한 경우라도 상관없이 백그라운드로 이동을 시킵니다. false일 경우 현재의 엑티비티가 루트(root)일 경우에만 백그라운드로 이동시킵니다. 루트라는 말은 태스크의 가장 첫번째(바닥)의 엑티비티임을 뜻합니다.

2. Intent 활용하기

1에서 소개해드린 방법으로도 백그라운드로 전환되지 않는 특정한 상황이 있다고 합니다. 그 경우 다음의 인텐트를 활용하는 방법을 사용하면 100% 전환이 이루어집니다. 1의 방법은 엑티비티를 백그라운드로 넘기는 방법이고 이방법은 홈스크린을 현재의 화면으로 끌고 오는 방법입니다. 간단하게 다음의 코드를 사용하시면 됩니다.

Intent intent = new Intent();
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);

다음은 위의 두가지 방법을 테스트 해볼수 있는 예제 소스를 올려드립니다. [다운로드]

사용자 삽입 이미지