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] 안드로이드 어플 배포를 위한 키스토어(Keystore) 생성 및 릴리즈

안드로이드 어플을 마켓에 혹은 타인에게 배포하기 위해서는 자신의 키를 생성하여 개발된 어플리케이션에 사인을 하여야 합니다. 개발자 혹은 회사당 1개의 키스토어만을 가지고 있으면 됩니다. 즉 한개의 어플리케이션당 한개의 키스토어를 사용하실 필요는 없습니다.

keytool을 사용하여 키스토어 생성하기

$ keytool -genkey -alias eye -keyalg RSA -validity 10000 -keystore eye.keystore

기본적으로 위와 같은 명령을 치시면 됩니다. -alias는 키 자체의 이름을 정의하며 -keystore는 키 파일을 저장할 위치를 정의합니다. 위와 같이 입력하면 현재 디렉토리에 파일이 생성됩니다. -validity의 경우에는 이 키스토어의 유효기간을 설정하는 것인데 단위는 일입니다. 위와 같이 3650을 입력하게 되면 10년이 됩니다. 10년으로 설정하면 Google Play에 등록시에 너무 기간이 짧다고 경고가 뜨게 변경되었더군요. 충분히 큰 시간으로 설정해 줍시다.

사용자 삽입 이미지

명령을 입력하면 위와같이 자잘한 것들을 물어오게 됩니다. 대충 상황에 맞게 입력하시면 됩니다. 여기서 주의할 점은 비밀번호를 두번 물어오게 되는데요 두가지를 다르게 하시던 같게 하시던 자유입니다만 잘 기억해 두셔야 합니다. 첫번째는 키스토어의 비밀번호이고 두번째는 Eye라고 이름 정한 키의 비밀번호 입니다. 키스토어는 여러개의 키를 포함할 수 있는데 그중에 하나의 키에 대한 비밀번호를 뜻합니다.

이클립스에서 키스토어를 이용하여 배포하기

사용자 삽입 이미지
위와 같이 프로젝트에 마우스 우클릭후에 Android Tools에 들어가시면 Export Signed Application Package가 있습니다. 이것을 선택합니다.

사용자 삽입 이미지
방금전 생성한 키스토어 파일을 선택한 뒤 키스토어 비밀번호를 입력하도록 합니다.

사용자 삽입 이미지
이번엔 생성한 키의 별칭을 선택하여 해당 비밀번호를 입력합니다. 이후에 APK파일을 저장할 경로를 넣어주면 정상적으로 키가 사인된 APK 파일이 생성됩니다.