안드로이드 Service

컴퓨터공부/안드로이드 2019.03.19 21:42 Posted by 아는 개발자 아는 개발자

0. 소개


Service 클래스는 안드로이드 앱에서 백그라운드 작업을 수행할 때 대표적으로 사용하는 라이브러리다. 앞서 설명한 AsyncTask와는 사용법이 완전히 다른데 2~3초 이내로 짧게 끝내야하는 AsyncTask와는 달리 Service는 오래도록 실행 할 수 있으며 AsyncTask처럼 UI 쓰레드와 Interaction 할 수 있는 기능은 없다. 그래서 화면과 무관한 작업인 네트워크 트랜잭션 처리나 음악을 재생할 때 사용된다.


1. 생성주기


액티비티와 독립된 생성주기를 가지고 있으며 별도의 컴포넌트로 동작하기 때문에 애플리케이션을 사용하지 않은 상태(UI가 화면에 있지 않은 상태) 여도 백그라운드에서 실행 될 수 있다. 폰 게임을 하는 중에도 카카오톡 메시지가 오고 쿠팡에서 쇼핑을 하는 도중에도 멜롬의 음악을 들을 수 있는 이유가 바로 이런 서비스 클래스의 특징 덕분이다. 경우에 따라선 애플리케이션 내에서 별도의 프로세스로 분리할 수도 있다.


2. 콜백함수 


Service 클래스의 콜백 함수를 통해 간단히 사용 방법을 익혀보자.


public void onCreate()


서비스가 생성 될 때 가장 먼저 실행되는 함수. 생성시 딱 한번만 호출되며 서비스 동작에 필요한 인스턴스를 선언하는 작업으로 주로 사용 한다.


public void onDestroy()


서비스가 종료될 때 호출되는 함수. onCreate에서 수행한 작업과 반대로 서비스가 종료하면서 인스턴스에 정리할 작업을 처리하는 일을 한다.


public int onStartCommand(Intent intent, int flags, int startId)


사용자의 요청을 처리하는 함수. 서비스를 처음 생성할 경우에는 onCreate 함수 다음에 불리나 생성 이후에는 이 함수로 바로 불린다. 전달 인자인 Intent에 필요한 작업을 전달할 수 있다.


3. 주의사항


단 주의할 것이 무한루프처럼 오래 걸리는 작업을 onStartCommand에 넣으면 ANR(Application Not Responding)에러가 발생하게 된다. 오래 실행하는 작업을 수행할 때 사용되는 라이브러린데 정작 사용하려니 에러가 발생하는게 생뚱맞게 들릴 수 있는데 이는 서비스 클래스 컴포넌트의 구조적인 이유 때문이다. onStartCommand함수는 서비스 작업 뿐만 아니라 사용자 interaction도 처리하는 메인쓰레드에서 담당하는데 이 함수가 빨리 종료되지 않는다면 사용자는 UI 작업을 처리하지 못하게 된다.


이러한 이유 때문에 오래 걸리는 작업은 onStartCommand에서 처리하되, 아래의 안드로이드 소스처럼 별도의 쓰레드를 생성해서 작업을 처리하도록 한다.


 
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    new Thread() {
        @Override
        public void run() {
            while (true) {
                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }
    }.start();

    return START_STICKY;
}


4. IntentService 


매번 쓰레드를 만들어서 작업을 처리한다면 여러 가지 작업을 동시에 처리할 수 있다는 이점도 있지만 개수가 많아짐에 따라 시스템 자원을 소모하게 되고 경우에 따라선 처리 시간은 중요하지 않고 작업이 순차적으로 처리하는 일이 필요한 경우 불필요한 오버헤드를 발생시키기도 한다. 차라리 이런 경우에는 여러 개의 쓰레드를 만들지 말고 하나의 쓰레드에서 작업을 하나씩 전달해주는 방식이 좋을 것 같기도 하다. 안드로이드에서는 이미 이런 경우를 고려해 IntentService 라는 클래스를 만들어 뒀다.


IntentService를 사용하면 메인 thread와 따로 도는 workqueue쓰레드가 생성되며 액티비티로부터 전달 받은 Intent를 순차적으로 아래의 onHandleIntent 함수에서 처리한다. 


protected void onHandleIntent(Intent intent)


onStartCommand 함수에서는 긴 작업을 별도의 쓰레드에서 처리했어야 했다면 IntentService의 onHandleIntent 함수안에서는 바로 길게 실행되는 작업을 둬도 상관 없다. 안드로이드가 알아서 작업을 처리해준다.

'컴퓨터공부 > 안드로이드' 카테고리의 다른 글

onSaveInstanceState  (0) 2019.07.15
JAVA의 static  (0) 2019.04.03
안드로이드 Service  (0) 2019.03.19
AsyncTask  (0) 2019.03.13
ViewPager와 PageAdapter  (0) 2019.03.05
px, dp, sp 개념 정리  (0) 2019.02.16