ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 안드로이드 서비스 : Android Service 정리, 종류, 생명주기
    너는 나의 에너지 2020. 2. 17. 20:52

     

    소셜 커머스 회사에서 두 달 동안 인턴을 진행하면서 정리했던 안드로이드 관련 내용들을 업로드하려고 한다. 참고로 인턴은 17년 여름에 했다. 

     

    안드로이드 Application을 구성하는 4가지 컴포넌트에는 Activity, Broadcast Receiver, Content Provider, Service 가 있다. 

     

    그중 Service는 Activity처럼 사용자와 상호 작용하는 컴포넌트가 아닌 Background에서 동작하는 컴포넌트다. 

    따라서, Activity가 종료되어 있는 상태에서도 동작하기 위해 만들어진 컴포넌트라고 할 수 있다. 인턴을 하면서 Music player를 개발했었는데, 이때 화면이 종료된 상태에서도 계속 노래를 재생해야 하기 때문에 개발하면서 Android Service를 이용했다. 

     

    만약 서비스가 실행되고 있는 상태라면, 안드로이드 OS에서는 해당 프로세스를 웬만하면 죽이지 않게 방지하고 관리해준다. 따라서 메모리 부족 등 특별한 경우를 제외하고는 백그라운드 동작으로 수행하도록 설계되었다. 

     

    Service 종류에는 2가지가 있는데, startService()를 이용하는 경우에는 서비스가 한 번 시작되면 백그라운드에서 무한정 실행되기 때문에 Music player에 적합한 서비스다. 이와 반대로 bindService()의 경우에는 서비스가 액티비티와 연결되어 있는 동안에만 실행되며, 액티비티가 사라지면 서비스도 동시에 소멸된다. 

     

    안드로이드는 프레임워크단이 Linux로 구현되어 있는 Linux기반의 프로그램이고, 메모리 관리 또한 Linux Kernel에서 해준다.

    여기서 주의해야 할 점은, 모든 컴포넌트들은 Main Thread (UI 작업을 처리해주는 Thread) 안에서 실행된다는 점이다. 서비스 역시 Main Thread에서 관리하기 때문에 Thread 작업이 필요한 경우에는 작업 Thread를 생성해서 관리해줘야 한다. 그렇지 않으면 ANR이 발생하여 종료되는 문제가 발생한다. 

     

    Service 주기는 onCreate() -> onStartCommand() 순이며, Service가 실행되고 있는 도중에 다시 한 번 startService() 메서드가 호출되면 onCreate()가 아닌 onStartCommand() 주기부터 실행하게 된다. 따라서 중요한 작업에 대해서는 onCreate()보다 onStartCommand() 메서드에 구현을 해야 한다. 

    서비스는 종료메서드인 stopService()가 호출되기 전까지는 프로세스에 의해 종료되더라도 다시 살아나는 구조이다. 프로세스에 의해 종료된 Service는 onCreate() -> onStartCommand() 순으로 주기를 타게 된다. 

     

    onStartCommand()의 리턴 타입에는 3가지가 있다. Service는 실행 시 startService(Intent Service)를 호출하는데 onStartCommand(Intent intent, int flags, int startId)에 intent로 value를 넘겨줄 수 있다. START_STICKY는 서비스가 강제 종료되었을 경우, 기존에 intent에 value 값이 설정되어 있다고 하더라도 시스템이 Service 재시작 시 intent 값을 null로 초시화시켜서 재시작한다. START_NOT_STICKY flag를 리턴해주면, 강제로 종료 된 서비스가 재시작하지 않는다. 따라서, 시스템에 의해 강제 종료되어도 괜찮은 작업에 사용한다. START_REDELIVER_INTENT는 START_STICKY와 마찬가지로 Service가 종료되어도 시스템이 다시 Service를 재시작시켜주지만 intent 값을 그대로 유지시켜 준다. startService() 호출 시 intent value 값을 사용한 경우라면, 이 flag를 사용해서 리턴 값을 설정해주면 된다. 

     

    댓글

Designed by Tistory.