-
[안드로이드] Thread and parallelism - 1앱개발/안드로이드 앱 개발 2018. 4. 3. 23:11
Thread-and-parallelism.md Udacity Android Basics: Networking - Threads & Parallelism 발췌
Thread and parallelism - 1
안드로이드에서도 당연히 쓰레드를 지원한다. 기본적으로 메인 쓰레드 하나에서만 동작을 하고 있지만 원하는 경우 언제든지 백그라운드 쓰레드를 추가하여 메인 쓰레드와 비동기적으로 다른 작업을 수행하도록 만들 수 있다. 보통 네트워크 작업이나 데이터베이스 저장 작업과 같이 UI와 관련 없는 일들을 백그라운드 쓰레드로 작업한다. 쓰레드에 관한 자세한 내용은 이 문서 를 참조하자.
네트워크 작업은 백그라운드에서 수행하자
이 github 리포지토리의
starting-point
브랜치를 다운로드 한뒤 안드로이드 스튜디오를 통해 실행해보자. 그러면 애플리케이션이 실행되지 않고 에러가 나오는 것을 볼 수 있다. 안드로이드 스튜디오의logcat
을 통해 살펴보면,NetworkOnMainThreadException
예외로 인해 실행하지 못함을 확인할 수 있다. 이것은 예외 이름 그대로 메인 쓰레드에서 네트워크 작업을 수행하려고 시도했기 때문이다.네트워크 작업은 서버에 연결, 데이터 전송/요청, 응답 데이터 처리, 응답 발송 등과 같이 다양하고 오래걸리는 작업을 수반하는게 일반적이다. 이러한 작업을 백그라운드 쓰레드가 아닌 메인 쓰레드에서 진행을 하게 되면, UI 관련 작업을 수행해야 하는 메인 쓰레드가 네트워크 관련 작업이 모두 종료될 동안 아무것도 하지 못한다. 이런 경우 앱이 정지된 것과 같은 모습을 보일 수 있으므로 매우 비효율적이기 때문에, 네트워크 작업과 같은 오래 걸리는 작업들은 반드시 백그라운드 쓰레드를 통해 수행해야 한다.
AsyncTask 클래스를 사용한 백그라운드 쓰레드
안드로이드 개발 환경에서는
AsyncTask
라는 추상 클래스 (abstract class)를 제공한다.AsyncTask
를 상속하여 사용하기 위해서는doInBackground()
메소드를 구현해야 한다. 메소드 이름에서 볼 수 있듯이 백그라운드에서 작업할 내용을 코딩하면 된다.백그라운드에서 필요한 작업을 수행한 뒤 UI를 업데이트 하고 싶을 경우에는 메인쓰레드에서 UI 업데이트를 수행해야 한다. 그러나
AsyncTask.doInBackground()
의 경우 백그라운드에서 수행되므로 해당 메소드 내에 UI 업데이트 코드를 작성해서는 안된다. 이를 지원하기 위해AsyncTask
클래스 내에서onPostExecute()
메소드를 제공한다. 해당 메소드는doInBackground()
메소드 수행이 완료된 뒤 자동적으로 호출 된다.어떤 경우에는 백그라운드 작업을 수행하기 전에 메인 쓰레드에서 특정 작업을 먼저 수행한 뒤 그에 따라서 백그라운드 작업이 달라지길 원하는 경우가 있을 수 있다. 그럴 때 사용할 수 있도록
onPreExecute()
메소드를 제공한다.onPostExecute()
메소드와 마찬가지로 메인쓰레드에서 동작하므로 UI 업데이트 작업또한 수행할 수 있다.백그라운드 작업을 통해 파일 다운로드 등과 같이 오래 걸리는 작업을 수행할 경우, UI 업데이트를 통해 현재 진행상황을 알려주고 싶은 경우가 있다. 이럴 때
doInBackground()
메소드에서는 UI 작업을 수행하면 안되므로, 이를 해결하기 위해onProgressUpdate()
메소드를 제공한다.doInBackground()
메소드 내에서 언제든지 원하는 경우 호출할 수 있으며 메인쓰레드에서 실행되므로 UI 업데이트도 진행할 수 있다. 실행은publishProgress()
메소드 호출을 통해 진행한다.예제
위의 예제는 안드로이드 공식 문서에서 제공하는 예제이다. 백그라운드 태스크를 생성한 이후에는
new DownloadFilesTask.execute(url1, url2, url3)
와 같이execute
메소드를 통해서 수행할 수 있다.AsyncTask
를 상속할 때<>
에 전달되는 파라미터들은 순서대로,doInBackground()
메소드에서 전달 받을 매개변수의 오브젝트 네임,onProgressUpdate()
에서 전달받을 매개변수의 오브젝트 네임,onPostExecute()
에서 전달받을 매개변수의 오브젝트 네임이다. 주의해야 할 점은 파라미터 자리에는 항상 오브젝트가 들어가야 하므로,int
,long
,void
등과 같은 원시 자료형을 사용하고자 하는 경우에는 그에 맞는Integer
,Long
,Void
등과 같이 오브젝트 타입을 사용해야 한다.첫 파라미터인
URL
은doInBackground(URL... urls)
를 보면 확인할 수 있다.URL...
처럼 오브젝트 네임 뒤에...
이 붙은 경우,varargs
라는 특수한 매개변수임을 포현한다. 이는 전달되는 변수가 0개 이상 (0,1,2,3 ...) 이 올 수 있음을 의미하며urls
는 항상 배열 형태를 유지한다.두번째 초기화 파라미터인
Long
은doInBackground()
메소드의 반환값이자onPostExecute(Long result)
메소드의 매개변수를 나타낸다.세번째 초기화 파라미터인
Integer
는onProgressUpdate(Integer... progress)
메소드의 매개변수이다. 이 메소드 또한...
을 통해서 전달되는 변수가 0개 이상이고,progress
가 항상 배열 형태임을 알 수 있다.onProgressUpdate()
메소드는 직접적으로 호출해서는 안되고 이미 구현되어 있는publishProgress()
메소드 호출을 통해 수행하여야 한다.'앱개발 > 안드로이드 앱 개발' 카테고리의 다른 글
[React Native] 설치 및 기본 실행 (0) 2018.05.18 [안드로이드] 안드로이드에서 HTTP 연결하고 데이터 처리하기 (0) 2018.03.30 안드로이드 앱 개발 관련 참고사이트 (0) 2018.02.13 [도전과제] 도전과제 2. 글자 수를 표시하는 SMS 입력 화면 (0) 2016.10.02 TextView(텍스트뷰)와 EditText(입력상자)의 다른 기능들 (0) 2016.10.01