이 글은 PC 버전 TISTORY에 최적화 되어있습니다.
서론
안드로이드에서 UI를 조작할 수 있는 방법에 대해서 두 가지를 배웠습니다.
AsyncTask 의 개념
AsyncTaskd의 동작 순서를 먼저 설명하고, 개념을 말씀드리도록 하겠습니다.
execute( ) 명령어를 통해 AsyncTask을 실행합니다.
AsyncTask로 백그라운드 작업을 실행하기 전에 onPreExcuted( )실행됩니다. 이 부분에는 이미지 로딩 작업이라면 로딩 중 이미지를 띄워 놓기 등, 스레드 작업 이전에 수행할 동작을 구현합니다.
새로 만든 스레드에서 백그라운드 작업을 수행합니다. execute( ) 메소드를 호출할 때 사용된 파라미터를 전달 받습니다.
doInBackground( ) 에서 중간 중간 진행 상태를 UI에 업데이트 하도록 하려면 publishProgress( ) 메소드를 호출 합니다.
onProgressUpdate( ) 메소드는 publishProgress( )가 호출 될 때 마다 자동으로 호출됩니다.
doInBackground( ) 메소드에서 작업이 끝나면 onPostExcuted( ) 로 결과 파라미터를 리턴하면서 그 리턴값을 통해 스레드 작업이 끝났을 때의 동작을 구현합니다.
여기서 핵심은 onPreExecute( ), onProgressUpadate( ), onPostExecute( ) 메소드는 메인 스레드에서 실행되므로 UI 객체에 자유롭게 접근할 수 있다는 것입니다.
필자가 AsyncTask 를 처음 봤을 때 헷갈렸던 부분은 바로 AsyncTask Generic 타입이었습니다. AsyncTask <Params, Progress, Result> 에서 인자1, 인자2, 인자3에 들어갈 값이 무엇이고 어디에 쓰인다는 것인지 알 수 없었던 것입니다.
Params : doInBackground 파라미터 타입이 되며, execute 메소드 인자 값이 됩니다.
Progress : doInBackground 작업 시 진행 단위의 타입으로 onProgressUpdate 파라미터 타입입니다.
Result : doInBackground 리턴값으로 onPostExecute 파라미터 타입입니다.
AsyncTask 의 사용법
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } // 버튼을 클릭하면 파일 다운로드 경로를 파라미터로 AsyncTask 실행 public void OnClick(View view) { switch (view.getId()) { case R.id.button: try { new DownloadFilesTask().execute(new URL("파일 다운로드 경로1")); } catch (MalformedURLException e) { e.printStackTrace(); } break; } } private class DownloadFilesTask extends AsyncTask{ @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected Long doInBackground(URL... urls) { // 전달된 URL 사용 작업 return total; } @Override protected void onProgressUpdate(Integer... progress) { // 파일 다운로드 퍼센티지 표시 작업 } @Override protected void onPostExecute(Long result) { // doInBackground 에서 받아온 total 값 사용 장소 } } }
AsyncTask 의 제약조건 및 단점
- API16(젤리빈) 미만 버전에서는 AsyncTask 선언을 UI Thread에서 해주지 않으면 오류가 발생한다. (API 16 이상(JELLY BEAN)의 버전에서는 자유롭게 사용해도 된다고합니다.)
- excutes(Params)는 UI 스레드에서 직접호출해야합니다
- 수동으로 onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) 호출하면 안됩니다.
- Task는 오직 한번만 실행될 수 있습니다.
- 하나의 객체이므로 재사용이 불가능합니다. (객체를 새롭게 생성하면 되지만 메모리 효율 나빠짐)
- 구현한 액티비티 종료 시 별도의 지시가 없다면 종료되지 않습니다.
- Activity 종료 후 재시작 시 AsyncTask의 Reference는 invalid 해지며 onPostExecute( ) 메소드는 새로운 Activit에 어떠한 영향도 끼치지 못합니다.
- AsyncTask의 기본 처리 작업 개수는 1개입니다. Async 하지 않은 AsyncTask의 변화를 아래에 적어 놓겠습니다.
Order of execution
When first introduced, AsyncTasks were executed serially on a single background thread. Starting with DONUT
, this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting with HONEYCOMB
, tasks are executed on a single thread to avoid common application errors caused by parallel execution.
If you truly want parallel execution, you can invoke executeOnExecutor(java.util.concurrent.Executor, Object[])
withTHREAD_POOL_EXECUTOR
.
참고사이트
'Frontend > Android' 카테고리의 다른 글
[안드로이드] RecyclerView 예제 (17) | 2016.07.12 |
---|---|
[안드로이드] RecyclerView란? (RecyclerView와 ListView 차이) (6) | 2016.07.11 |
[안드로이드] 안드로이드 메모리 관리 (Weak Reference와 Soft Reference) (0) | 2016.07.08 |
[안드로이드] runOnUiThread란? (개념과 사용법) (5) | 2016.07.07 |
[안드로이드] Thread, Handler, Looper를 통한 백그라운드 처리 (10) | 2016.07.06 |
[안드로이드] 스레드(Thread) 개념 및 사용법 (5) | 2016.07.06 |