Android - Service

Posted by RoadtoS7 on December 26, 2020 · 6 mins read

:convenience_store: Service

:one: 정의

  • 서비스는 화면(UI)없이 백그라운드에서 실행되는 Android 구성요소
  • 주로 사용할 때: 애플리케이션을 백그라운드에서 계속 실행시킬 때 사용한다.
    • 예) 사용자가 다른 앱을 사용하는 동안 서비스는 백그라운드에서 음악을 계속해서 재생시킬 수 있다.
    • 예) 액티비티와 사용자간의 상호작용을 막지 않으면서, 네트워크를 통해 데이터를 가지고 올 수 있다.
  • 백그라운드: 화면뒤의 백단, 공간
  • Android 구성 요소 중 하나이기 때문에 manifest 파일에 반드시 선언해야 한다.

:two: 역할

  • 오래 실행되는 작업을 수행한다. 또는 다른 프로세스의 작업을 수행한다.
  • 다른 애플리케이션 구성요소 서비스를 시작할 수 있다. 혹은 서비스와 상호작용하기 위해 서비스에 바인딩할 수 있다.
  • 사용자가 다른 애플리케이션으로 전환하더라도 계속해서 실행된다.
  • Android의 다른 구성요소를 서비스에 바인딩하여 서비스와 상호작용시킬 수 있다.
  • 프로세스간 통신도 수행할 수 있다.
    • 예를 들어서 어떤 서비스는 네트워크 트랜잭션을 처리하고, 다른 서비스는 음악을 재생하거나, 파일 I/O를 수행 및 콘첸트 프로바이더와 상호작용할 수 있으며, 이 모든 것을 백그라운드에서 수행할 수 있다.

:three: 만드는 방법

  • 일반적으로 Service를 상속받아서 만든다.
  • 서비스 수명주기에 중요한 것들을 처리하는 메서드들을 모두 오버라이딩 해야한다.
  • 서비스와 안드로이드 구성요소를 바인딩하는 경우, 바인딩된 요소를 메서드도 넣어줘야 한다.

:bulb: 앱이 API레벨 26이상을 타겟으로 한다면, 앱이 포그라운드에 있지 않을 때, 백그라운드 서비스 실행에 제한이 있다. 백그라운드 서비스 실행을 해야하는 경우 앱은 WorkManager를 통한 예약된 작업을 사용해야한다.

:bulb: 서비스 바인딩
서비스가 다른 구성요소와 클라이언트, 서버 인터페이스를 이루어서 서버의 역할을 하는 것을 말한다.
즉, 서비스는 다른 구성요소가 자신에게 바인딩 될 수 있도록 하고, 바인딩 된 후에는 요청을 보내고, 응답을 수신하며 프로세스간 통신을 수행할 수 있다.

:four: 서비스 유형

  • 시스템에서 서비스를 어떻게 다루도록 하는지에 따라, 의미적으로 다른 2개의 서비스가 존재한다.
    1. 시작된 서비스: 시작된 서비스는 시스템에게 자신들의 작업이 끝날 때까지 계속해서 자신을 실행하도록 한다.
    • 시작된 서비스를 이용해서 백그라운드에서 데이터를 동기화 하거나,
      사용자가 앱을 떠나더라도 음악을 계속해서 실행시키도록 할 수 있다.
    • 백그라운드에서 데이터를 동기화하는 서비스와, 음악을 계속해서 실행시키는 서비스 이 두가지도 시스템에서 이들을 다루는 방식이 서로 다르기 때문에 두가지 유형으로 나누어진다.
    1. 음악을 실행시키는 서비스: 사용자가 직접적으로 인지하는 서비스이다. 따라서 이러한 서비스를 실행할 때, 앱은 시스템에게 사용자가 이 서비스가 실행되고 있음을 알 수 있도록 알림을 전달하는 포그라운드 서비스가 되도록 요청한다. 시스템은 이를 통해서 이 서비스가 사용자가 직접적으로 인지하는 서비스임을 알게 되고, 해당 서비스가 계속해서 실행되도록 매우 노력한다. (왜냐하면 이 서비스가 종료되면 사용자가 좋아하지 않을 것이기 때문이다.)

    2. 일반적인 백그라운드 서비스: 사용자가 해당 서비스가 실행되고 있다고, 직접적으로 인지하는 서비스가 아니다.
      따라서 시스템은 서비스를 관리하는데 더 자유롭다.
      즉, 시스템은 사용자가 당장 더 필요한 작업을 위해서 RAM이 필요하다면, 이 서비스를 중단시켰다가 나중에 다시 실행시킬 수 있다.

  1. 바인딩된 서비스: 다른 앱 혹은 시스템이 서비스를 이용해야할 때 쓰이는 서비스이다. 일반적으로 다른 프로세스에게 API를 제공하는 서비스이다.
  • 따라서 만약 프로세스 A가 프로세스 B의 서비스에 바인딩되어 있다면, 시스템은 두 프로세스간에 의존성이 있다는 것을 안다. 게다가 프로세스 A를 실행시키기 위해서 프로세스 B를 계속해서 실행시켜야 한다는 것을 안다.
  • 또한 사용자가 프로세스 A에 관심을 가지고 있다면, 시스템은 프로세스 B도 사용자가 관심을 가지고 있는 것으로 간주해야하는 것을 안다.
  • 이러한 유연성덕분에 모든 종류의 상위 시스템 요소들에 매우 유용한 구성요소가 되었다.
  • 라이브 배경화면, 알람 리스너, 화면 보호기, 입력 메서드, 접근성 서비스 및 여타 핵심적인 시스템 기능들은 모두 애플리케이션이 구현한 서비스로 만들어지며, 시스템은 해당 서비스가 실행되어야할 때, 서비스에 바인딩된다.

  • 정리하자면, 서비스 유형에는 3가지가 있다.
    1. 포그라운드 서비스(시작된 서비스)
    2. 백그라운드 서비스(시작된 서비스)
    3. 바인딩 서비스

1. 포그라운드 서비스(Foregound Service)

  • 사용자에게 잘 보장소에 보이는 작업을 수행하는 서비스이다.
  • 예를 들어서 오디오 앱이라면 소리를 재생하기 위해서 포그라운드 서비스를 사용한다.
  • 포그라운드 서비스는 알림 을 표시해야 한다.
  • 포그라운드 서비스는 앱과 사용자가 상호작용하지 않는 동안에도 계속해서 동작한다.

:bulb: Workmanager가 작업을 예약하는데 더 유연한 방법을 제공한다.
그리고 필요하다면 이 작업들을 포그라운드 서비스로서 동작하도록 만들 수 있다.
대부분의 경우 포그라운드 서비스를 직접 이용하는 것보다 Workmanager를 이용하는 것이 더 낫다.

2. 백그라운드 서비스(Background Service)

  • 사용자에게 잘 보이지 않는 작업을 수행하는 서비스이다.
  • 예를 들어서 앱이 기기의 저장소에 접근하는 서비스를 사용한다면, 해당 서비스는 백그라운드 서비스이다.

:bulb: 앱이 API 레벨 26 이상을 타겟으로 한다면, 시스템은 앱이 포그라운드에 있지 않을 때 백그라운드 서비스를 실행하는 것에 제제를 가한다.
예를 들어서, 백그라운드 서비스로 위치 정보에 접근해서는 안된다.
대신에 Workmanager를 이용하여 접근해야 한다.

3. 바인딩된 서비스(Bound Service)

  • 애플리케이션 구성요소가 bindService()를 호출하여 서비스에 바인딩하면, 서비스는 바인딩된다. (바인딩된 서비스가 된다)
  • 바인딩된 서비스는 애플리케이션 구성요소들이 자신과 상호작용할 수 있도록 클라이언트-서버 인터페이스를 제공한다.
  • 구성요소들은 이 인터페이스를 통해서 서비스에게 요청을 보내고, 응답을 받을 뿐만 아니라 프로세스간 통신을 통해 여러 프로세스에 걸쳐서 이를 수행할 수 있다.
  • 바인딩된 서비스는 자신과 바인딩된 구성요소가 있는 동안에만 동작한다.
    따라서 자신과 바인딩된 요소가 없다면, 서비스는 메모리에서 제거된다.
  • 여러개의 구성요소가 동시에 하나의 서비스에 바인딩될 수 있다.

:bulb: 바인딩된 서비스이면서 포그라운드 서비스이거나 백그라운드 서비스일 수 있다.

  • 즉, 앱이 포그라운드 상태가 아니더라도 계속 실행되면서 다른 구성요소가 바인딩할 수 있는 서비스를 만들 수 있다.
  • 이는 어떤 콜백 메서드를 구현하느냐에 따라서 다르다.
    1. onStartCommand() 메서드를 구현하면, 계속 실행되는 서비스를 만들 수 있다.
    2. onBind() 메서드를 구현하면, 다른 구성요소가 해당 서비스에 바인딩할 수 있다.
  • 바인딩된 서비스이든 아니든, 모든 애플리케이션 구성요소는 activity를 사용하는 것과 같이 Intent를 이용하여 서비스를 사용할 수 있다. 심지어 서비스와 다른 애플리케이션에 위치한 구성요소도 서비스를 이용할 수 있다.
  • 하지만 manifest 파일에서 서비스를 private으로 선언하면, 다른 애플리케이션 구성요소가 접근하는 걸 막을 수 있다.
  • 이 부분은 Manifest에 서비스를 선언하는 방법을 보면 더 자세히 알 수 있다.