Android/이론 학습

[Android] Service 의 타입과 사용법 그리고 권장사항

노소래 2022. 2. 23. 10:55

[서비스란?]

  • 안드로이드 앱 4대 컴포넌트 중하나이다.  즉 앱 프로세스의 진입점 중 하나이다.
  • (유저가 앱과 상호작용하고 있지 않아도) 백그라운드에서 길게 실행되는 연산들을 수행할 수 있다. (Activity 와는 다르게 UI 제공 x)
  •  그러니 어플리케이션이 실행 중이지 않을 때도 ((아마) 앱 프로세스를 강제 종료 하지 않는 한) 작업해야하는 경우 서비스를 사용. (어플리케이션이 실행 중일 때만 작업해야하는 경운 스레드권장)
  • 다른 앱으로 이동해도 한동안 실행을 지속할 수 있다.
  • 한 컴포넌트와 bind 하여 소통할 수 있고, IPC(interprocess communication) 도 가능
  • 주의할 점은 위 설명에서 백그라운드라는 말이 나왔다고 해서 서비스가 메인스레드(UI스레드) 외의 다른 스레드에서 작업한다고 착각하면 안된다. (예를 들어, 메인스레드로 오래걸리는 통신작업 하면 ANR 을 마주할 수 있으니..) 서비스는 디폴트로 메인스레드에서 실행된다!
  • 또 주의할 점은 API 레벨 26이상부터 앱이 포그라운드가 아니라면 백그라운드 서비스를 만들고 상요하는데 제한이 걸린다.

 

[서비스의 타입]

  • Foreground
    유저의 눈에 보이지 않지만 유저가 인지할 수 있는 작업들을 수행
    반드시 Notification 을 보여주어야한다. (그래야 유저가 서비스가 실행중임을 알 수 있으니까)
    서비스가 만들어지고 5초이내에 startForeground 호출해야?!
  • Background
    유저가 인지하지 못하는 작업들을 수행
    예를들면 저장소 압축
  • Bound
    다른 앱 컴포넌트가 서비스에 bindService 메소드를 호출해서 바인드 됐을 때만 실행됨
    여러 컴포넌트가 동시에 바인드될 수 있고 모두 unbind 되면 서비스가 파괴됨
    client/server 인터페이스를 제공하여 바인드한 컴포넌트가 요청하고 결과를 받는 상호작용을할 수 있음
    이것으로 IPC 까지 가능

 

[사용법 요약]

  • Service 를 상속하는 서브클래스를 만든다.
  • 서브클래스를 Manifest 에 등록한다. (https://developer.android.com/guide/topics/manifest/service-element) 참고
  • 서비스를 상황에 맞게 컨트롤하기 위해 시스템이 호출해주는 Service 의 주요 Callback 메소드를 구현해준다. (아래 서비스의 lifecycle 섹션 그림을 보면 더 잘 이해될 것이다.)
    • onStartCommand
      다른 컴포넌트가 서비스를 시작함녀 시스템이 startService 를 호출해서 onStartCommand 를 호출
      일단 시작하면 백그라운드에서 계속 실행될 수 있기 때문에
      개발자는 시스템 리소스나 배터리 낭비를 막기 위해 (binding 만 원하는 게 아니라면) 서비스 내에서 stopSelf 나 서비스를 싲가한 다른 컴포넌트에서 stopService 를 호출하여 실행을 정지시킬 필요가 있다.

      같은 서비스를 여러 번 실행시키는 상황에서는 stopService 를 하나만 호출해도 그 여러 개 모두 죽기 때문에 stopSelf 에 id 를 전달해서 그 id 하나만 종료시킬 수 있다.
      onStartCommand 에서 반환하는 Int 값으로 서비스가 죽었을 때 다시시작하는 방식을 설정해줄 수 있다.
    • onBind
      다른 컴포넌트가 서비스에 바인드할 때 시스템이 bindService 를 호출해서 onBind 를 호출
      앞서 Bound 타입 서비스는 client/server 구조를 가진다고 했는데
      개발자는 여기서 리턴해주는 IBinder 로 clients 가 서비스와 소통할 수 있게 해준다.  
    • onCreate
      서비스가 초기에 만들어질 때 한 번 호출됨 (즉 서비스가 이미 실행중이라면 호출되지 않는다.)
      개발자는 여기서 리소스 초기화
    • onDestroy
      서비스가 더이상 사용되지 않고 파괴될 때
      개발자는 여기서 리소스 해제 
  • 다른 컴포넌트에서 startService, onStartService, onBind 를 호출해준다.

 

[Service 의 lifecycle]

Activity 에 비하면 매우 단순하지만

눈에 보이지 않기 때문에 의도치 않게 계속 실행되어 자원을 낭비하는 것을 막자

 

 

 

맘아픈 점 두 가지

자세히 작성했었는데 다 날라가서 마음이 아프다...

그리고 포그라운드 서비스가 아니라면 WorkManager 를 사용하는 것을 권장한다는 점...