ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [ 안드로이드 프로그래밍 Next Step ] 6.0. 서비스
    Book Study/안드로이드 프로그래밍 NextStep 2022. 4. 4. 19:43
    반응형

     

    이 글은 [안드로이드 프로그래밍 Next Step] 책을 읽고 안드로이드 공식 문서 내용를 더해 정리한 포스트입니다.

    책의 일부는 공부하지 않아서 업로드 되지 않을 수 있으며, 포스트의 순서도 보장되지 않습니다.

     


    서비스

    UI를 제공하지 않고 백그라운드에서 장기 실행 작업을 수행할 수 있는 안드로이드 컴포넌트.

    눈에 보이는 컴포넌트가 아니어서 백그라운드라는 말을 사용한 것이지, 서비스 자체가 메인 스레드가 아닌 다른 스레드에서 실행하는 것으로 착각해서는 안된다. 서비스의 생명주기 메서드는 UI 스레드에서 실행되기 때문에 이 때문에 다른 UI 이벤트가 지연될 수 있다.

    서비스에서 별도의 스레드를 만들어서 작업을 수행하지 않는다면, ANR(Application Not Response) 에러가 발생할 수 있다.

     

    스레드를 안정적으로 돌릴 수 있는 컴포넌트라고 생각하면 좋다.


    서비스의 종류

    서비스는 종류에 상관 없이 다른 앱 컴포넌트에서 사용할 수 있다. (startService(Intent) 가능) Service를 다른 앱에서 접근하지 못하도록 하기 위해서 Manifest 파일에 해당 서비스를 비공개로 설정 해주어야 한다.

     

    1. Foreground Service

    사용자가 인식할 수 있는 작업을 수행하는 서비스. 음악 플레이어 같은 앱을 재생하기 위해 Foreground Service를 사용한다. 사용자가 앱과 상호 작용 하지 않을 때에도 Foreground Service는 계속 실행 된다. 사용자가 서비스가 실행 중임을 인식할 수 있도록 Notification을 표시해야 한다. 서비스가 중지되거나 Foreground Service에서 삭제되지 않는 한 이 Notification을 해제할 수 없다.

     

    공식 문서에서는 Foreground Service를 직접 사용하는 것 보다 WorkManager API를 사용하는 것을 권장한다.

    작업을 더 유연하게 스케줄링 할 수 있으며 필요에 의해 Foreground Service로 실행할 수 있기 때문이다.

     

    2. Background Service

    사용자에게 보이지 않는 작업을 수행 한다. 파일 다운로드나 압축 등을 위해 Background Service를 사용할 수 있다.

     

    API 26 버전 이후 부터는 앱 자체가 포그라운드에 있지 않을 때 Background Service 실행에 제한이 생겼다. Background Service에서는 위치정보를 가져올 수 없으며, WorkManager를 사용해서 작업을 예약해야 한다.

     

    3. Bound Service

    bindService()를 호출할 때 서비스가 바인드 된다. BoundService는 Component과 Service 간 상호 작용할 수 있는 클라이언트-서버 인터페이스를 제공함으로써 요청 전송, 결과 수신, IPC(Inter Process Communition)를 프로세스 전체에서 수행할 수 있게 해준다.

     

    BoundService는 다른 앱 Component가 바인딩 된 경우에만 실행된다. 여러 Component가 동시에 Service에 바인딩할 수도 있지만, 바인딩 된 모든 Component들이 언바인드 되면 서비스는 destroy된다. 

     


     

    안드로이드 프로세스 우선순위

    https://developer.android.com/guide/components/activities/process-lifecycle

    앱이 스레드 실행을 마치기 전에 백 키로 앱을 빠져나오거나 홈 키로 나가서 다른 앱을 오랫동안 사용하면, 프로세스가 종료될 수 있다. 메모리가 부족할 경우에 LMK(Low memory killer)는 우선순위가 높지 않은 프로세스를 종료한다. LMK는 스레드 실행 도중에도 앱 프로세스를 종료할 수 있다.

    1. Foreground Process (포그라운드 프로세스)

    안드로이드 컴포넌트가 포그라운드에서 실행되는 프로세스이다. 메모리가 부족할 때에도 가장 마지막까지 남을 수 있는 프로세스이다.

    1. 사용자와 상호 작용하는 액티비티를 가지고 있는 프로세스 (onResume 까지 실행된 액티비티)
    2. 서비스 생명주기 콜백을 실행시키는 Service를 가지고 있는 프로세스
    3. onReceive()를 실행하는 브로드캐스트 리시버를 가지고 있는 프로세스

    2. Visible Process (가시 프로세스)

    포그라운드 컴포넌트를 가지고있지는 않지만 사용자가 보는 화면에 영향이 있는 프로세스이다.

    이 프로세스들은 매우 중요한 프로세스로 간주되며, 모든 포그라운드 프로세스를 계속 실행하기 위해 필요한 경우가 아니면 종료되지 않는다.

    1. 액티비티가 다이얼로그나 투명한 액티비티로 부터 가려진 경우 (onPause까지 실행된 액티비티)
    2. 포그라운드 서비스로써 실행된 서비스(startForeground()) 를 가진 프로세스. (사용자가 서비스를 인지하거나 보이는 것으로 취급된 서비스.)
    3. Input method service, live wallpaper 등 같은 사용자가 인식하고 있는 특정 기능을 사용하는 서비스를 호스팅 하는 프로세스

    3. Service Process (서비스 프로세스)

    startService()로 실행된 서비스를 가지고 있는 프로세스. 이런 프로세스는 사용자가 직접 볼 수 없지만 일반적으로 백그라운드 네트워크 데이터의 업로드나 다운로드 등 사용자가 관심을 가지는 작업을 하기 때문에 포그라운드나 가시 프로세스를 유지하는 데 충분한 메모리가 있다면 시스템에서는 이 서비스 프로세스를 항상 실행 상태로 유지한다.

     

    30분이 넘어가는 긴 작업을 하는 서비스 프로세스는 캐시 프로세스로 중요도가 내려갈 수 있다. 메모리 누수 등의 과도한 자원을 사용하는 서비스의 중요도를 내림으로써 사용자에게 더 좋은 사용 경험 제공을 하지 못하는 경우를 피할 수 있다.

    4. Cached Process (캐시 프로세스)

    캐시된 프로세스는 현재 필요하지 않아서, 다른 곳에 메모리 같은 리소스가 필요할 때 시스템에서 이 프로세스를 언제든지 종료할 수 있다.

    사용자가 백 키로 액티비티를 모두 종료하고 활성화된 컴포넌트가 없는 경우 캐시 프로세스가 된다.(onStop 호출된 이후) 이런 프로세스가 한동안 메모리에 유지되는데, 다음에 컴포넌트를 빠르게 띄우기 위해서 캐시 해두는 것이다.

     


     

    서비스의 시작 방법

    서비스를 시작하는 방법으로 startService()bindService() 두 가지가 있다. 위 사진은 각각 생명주기를 구분한 것이다.

    그림에는 Unbounded Service라는 단어가 있는데, 바인드 되었다가 해제되었다는 의미로 오해할 수 있기 때문에 StartedService가 맞겠다. 공식 문서에서도 대단락에서는 startedService라는 용어를 사용한다.

     

    서비스는 보통 started 또는 bound 서비스로 존재하는데, started이면서 bound일 수도 있다. 예를 들어 앱이 다운로드를 진행한다면, 화면을 종료해도 다운로드는 지속되어야하고 (started service), 다시 화면에 진입해도 진행률을 표시해야 한다.(bound service)

    반응형

    댓글

Designed by Tistory.