[ 앱 개발자 도전기 : 안드로이드 ] 안드로이드의 Service 종류 및 Service LifeCycle

0

App_Dev : Android.

목록 보기
7/11
post-thumbnail

[ 앱 개발자 도전기 : 안드로이드 ] 안드로이드의 Service 종류 및 Service LifeCycle

∇ Service 종류 및 Service LifeCycle

목   차

1. 안드로이드 : Service란 ?
2. Service의 종류 : Foreground / Background / Bound 
3. Service의 형태 : Started / Bound
4. Service Lifecycle & 콜백함수

Ⅰ. 안드로이드 : Service란 ?

🩻 Service의 정의.

◇ 안드로이드 4대 컴포넌트 중 하나로 "백그라운드 업무"를 담당하기 위한 컴포넌트.

    √ Activity처럼 사용자와 상호작용하는 컴포넌트가 아닌,
      백 그라운드에서 오랜 시간 동안 수행되는 업무를 처리하기 위한 컴포넌트.
      
    √ 사용자에게 인터페이스를 제공하지 않고, 백그라운드에서 오래 실행되는 작업을 수행할 수 있는 애플리케이션 구성 요소.
        ex) 파일 다운로드, 데이터 체크, 데이터 처리, 네트워크 트랜잭션, 음악 재생, Content Provicder와의 상호작용 등등..
          

√ 액티비티가 종료되어 있는 상태(다른앱으로 전환)에서도 동작하기 위해 만들어진 컴포넌트.

   ex) 화면이 종료된 상태에서도 노래 재생.
   
   ※ 서비스가 실행되고 있는 상태라면, 안드로이드 OS에서는 해당 프로세스를 웬만한 경우에 죽이지 않고 관리합니다. 
   메모리 부족 등의 특별한 경우를 제외하고 백그라운드 동작으로 수행하도록 설계됨.
   
   

@서비스의 실행.

-  서비스의 실행은 액티비티와 같이 다른 컴포넌트에서 startService() 메소드 호출에 의해 이루어집니다.


-  서비스는 자신을 실행시킨 컴포넌트와는 독립적인 Life Cycle 을 가집니다.


   백그라운드에서 독립적으로 실행 가능(자신을 실행시킨 컴포넌트가 더 이상 존재하지 않아도!)

-> 자신이 stopSelf()를 호출하거나, 다른 컴포넌트가 stopService()를 호출해서 중단해야 함

-  서비스는 필요한 경우, 
  사용할 Intent 를 넘겨 받을 수 있음 -> startService() 를 호출하며 Intent를 전달합니다.

-> 넘겨 받은 Intent는 onStartCommand() 메소드에서 핸들링 가능합니다.

🩻 Service의 특징.

 1) "사용자"와 상호작용 불가.
 2) Activity의 생명주기에 종속되어 있지 않습니다.
 3) 별도의 스레드에서 동작하지 않습니다. 즉 호스팅 프로세스의 '메인 스레드'에서 작동합니다.
          
        -  안드로이는 프레임워크단이 Linux로 구현되어 있는 Linux 기반의 프로그램이고, 메모리 관리 또한 Linux Kernel에서 해준다.


        -  주의할 점은, 모든 컴포넌트들이 Main Thread(UI 작업을 처리해주는 Thread) 안에서 실행된다는 것



        ->  서비스 역시 Main Thread에서 관리하므로, 
            Thread 작업이 필요한 경우에는 작업 Thread 를 생성해서 관리해야 함



       ->  그렇지 않으면, ANR(Activity Not Response)가 발생하여 종료되는 문제 발생



 4) 현재 비-활성화된, 액티비티보다 우선순위가 높습니다.
 
 

Ⅱ. Service의 종류 : Foreground / Background / Bound

🩻 Foreground Service

◎ Foreground Service

1) Foreground Service는 서비스가 수행하는 동작을 사용자에게 알릴 때 사용합니다.

    ==> 사용자에게 Notification을 통해서 서비스가 실행되고 있음을 알려야 합니다.
    
    Ex) 음악 플레이어의 경우, 현재 실행중인 음악 등의 정보를 Notification 을 통해 알려주도록 함!

        이 Notification은 서비스가 중단되거나 Foreground 에서 제거되지 않는 이상 지울 수 없습니다.

      ++  대부분의 경우, WorkManager(Jetpack에 있는 API)를 사용하는 것이,
           Foreground Service 를 직접 사용하는 것 보다 낫다고 한다.
           

2) Foreground Service 는 활성화된 액티비티와 동일한 우선순위를 가진다.

  -  따라서, 시스템에 메모리가 부족하더라고 Android System에 의해 종료될 확률이 낮다.

🩻 Background Service

◎ Background Service

1)  사용자에게 보이지 않는 백그라운드 작업 수행


2)  시스템 리소스가 부족할 경우 강제 종료 가능
  • API 26(오레오) 이상부터는 앱이 포그라운드에 있지 않을 때,
    백그라운드 서비스를 강제 종료
    시킵니다.

-> 따라서, 즉각적인 실행을 요구하는 작업에는 포그라운드 서비스를,
예약된 작업일 경우에는 알람매니저나 워크 매니저를 활용
해야 합니다.

🩻 Bound Service

◎ Bound Service

1) bound service 는 IBinder 라는 인터페이스로 서버-클라이언트 관계처럼 서비스와 상호작용

여러 프로세스에서 같은 서비스에 바인딩하여 작업 수행 가능

 -> 여러 프로세스에 걸쳐 프로세스 간 통신(IPC, Interprocess communication)을 수행할 수 있음

2) Bind Service는 여기에 바인딩된 컴포넌트들이 전부 바인딩 해제되면, 서비스가 소멸

Ⅲ. Service의 형태 : Started / Bound

1. Started Service

-  startService()를 호출하여 시작됩니다.

-  서비스가 한 번 시작되면 -> 백그라운드에서 무한정 실행됩니다.

2. Bound Service

-  bindService()를 호출하여 시작합니다.


-  서비스가 액티비티와 연결되어 있는 동안에만 실행되고, 액티비티가 사라지면 서비스도 동시에 소멸됩니다.

3. 한 서비스에서 bindService()와 startService() 를 전부 실행 가능

-  startService()로 무한히 실행하게 하고,
-  bindService()를 통해 앱의 구성요소에서 통신이 가능합니다.

-> 이 경우, 모든 구성 요소에서 바인드가 해제되더라도 서비스가 종료되지 않음!

-> 반드시 stopService() 혹은 stopSelf()를 통해 서비스를 종료시켜야 함.!

Ⅳ. Service Lifecycle & 콜백함수

🩻 Service 클래스

class MyService : Service() {
	override fun onBind(intent: Intent): IBinder? {
    	return null
    }
}
  • Service 를 상속 받아 작성

  • onBind() 함수는 내부를 구현하지 않더라도 반드시 오버라이드 받아야 한다.

🩻 Manifest 등록

서비스도 컴포넌트이기 때문에 등록해 주어야 합니다.

<service
	android:name=".MyService"
    android:enabled="true"
    android:exported="true"></service>
  • AndroidManifest.xml 에 등록

service 태그로 등록하며 name 속성은 생략 불가

🩻 startService()

val intent = Intent(this, MyService::class.java)
startService(intent)
  • startService() 에 의한 실행

  • 외부 앱의 서비스라면 setPackage() 함수를 이용해 실행하고자 하는 앱의 패키지명(식별자) 을 명시

🩻 stopService()

4개의 컴포넌트 중에 유일하게 서비스만 종료하기 위한 인텐트 함수도 존재합니다.

❓ 제공하는 이유는
서비스는 한 번 구동되면 대부분 작업 시간이 길고,
화면 반응성이 없어 유저에 의해 종료될 수 없기 때문입니다.

val intent = Intent(this, MyService::class.java)
stopService(intent)
  • 서비스를 종료 시키고 싶다면 stopService() 함수로 인텐트 발생시키기.

  • 안드로이드 서비스를 생성하기 위해서는 Service 를 Implemet 해야하고,
  • 안드로이드의 LifeCycle을 핸들링 하기 위한 콜백 메소드들을 재정의하고,
  • 필요한 경우 바인드를 위한 메소드도 Override 해야함!!

만약, bindService()를 통해 서비스를 생성했다면,
즉, onStartCommand()를 호출하지 않았으면 바인딩된 서비스가 종료되면 -> 시스템에서 서비스를 제거함

안드로이드는, 디바이스에 메모리가 부족할 때 -> 서비스를 종료해서 -> 시스템 디바이스 자원을 회복한다.
서비스가 백그라운드에서 오래 실행될수록 시스템에 의해 서비스가 종료되기 쉽다.
만약, 시스템이 자원을 확보하기 위해 서비스를 죽이면 -> 서비스를 다시 실행할 수 있는 자원이 확보되는 경우 onStartCommand() 를 다시 실행한다.

🩻 Background Service 생명주기

  • StartService()를 통해 최소 서비스 실행 시 onCreate()가 호출 됩니다.
  -> 그 이후에는 StartCommand()가 호출 됩니다.



 -> 서비스를 종료하기 위해서는 stopService()를 실행하거나 / 서비스 자체에서 stopSelf() 를 실행합니다.



 -> 그러면, onDestroy()가 호출되어 서비스가 종료 됩니다.
 
 

🩻 Bind Service 생명주기

  • bindService()를 통해 최초 바인드 시 -> onCreate() 실행. -> 그 후 onBind()가 호출됨.!
  • 바인드를 해제하기 위해서는 unbindService()를 실행하면 -> onUnBind()가 호출되고 -> onDestroy()가 호출되어 서비스가 종료됨!

🩻 Intent Service 생명주기

- 비동기 처리에 용이

  • 기본 스레드와는 별개로,
    onStartCommand()에 전달된 모든 인텐트 실행을 위한 작업 스레드를 생성함
  A. 전달된 인텐트는 작업을 위한 큐에 순차적으로 쌓이고

  B. 루퍼에 의해 차례대로 onHandleIntent() 에 전달된다.

  C. onHandleIntent()에서 작업이 완료되면 서비스를 종료함

  D. 별도의 멀티 스레딩 처리를 고민하지 않아도 된다.
  • 다른 함수는 오버라이딩하지 않아도 O
  • onStartCommand()는 반드시 오버라이딩 + super.onStartCommand()를 호출해야 함!

0개의 댓글

관련 채용 정보