-
Component - ServiceAndroid 2021. 10. 24. 18:15
Service 역할
- Service는 Application이 Background 상태에서 계속 실행하기 위한 다목적 진입점이다. 간단히 Application이 Background에서 실행해야 하는 작업을 위한 Component라고 할 수 있다.
- Activity와 다르게 UI를 제공하지 않는 Component이다. 이에따라 UI가 없기에 Background에서 오랜 시간 동안 작업을 수행하거나 Remote Process를 위한 작업을 수행한다.
위 항목에 대한 내용을 풀어보자.
Service는 Application이 Background 상태에서 계속 실행하기 위한 목적을 가지고 있는데 이는 다시 말해 한번 시작된 Service는 작업이 완료될때 까지 시작된 Service를 계속 실행하도록 System에게 지시를 할 수 있다.
이에따라 System은 실행된 Service를 처리하도록 지시를 받고 유형에 따라 Service를 처리하는 방식을 변경시킨다.
System이 처리하는 방식에는 다음 3가지 유형으로 나눌 수 있는데 다음과 같다.
1) Foreground 유형
Foreground Service는 사용자가 인식할 수 있도록 하는 작업을 수행해야 한다. 따라서 Application은 사용자에게 Notification을 보내고 해당하는 작업을 Foreground 유형으로 변경하도록 System에 지시를 한다.
이와 같이 Foreground 유형으로 변경될 경우에 System은 해당 Service의 Process를 사용자가 앱과 상호작용을 하지 않아도 계속 유지되도록 관리한다. 만약 실행 중인 Service의 Notification을 닫을 경우(종료할 경우) 실행 중인 Service를 Stop 시킨다.
Foreground Service 유형의 대표적인 기능은 음악 재생을 예로 들 수 있다.
음악 재생 2) Background 유형
Background Service는 사용자가 인식하지 못하는 작업을 수행한다. 하지만 Background Service는 이제 잘 사용하지 않는데 이유는
동시에 실행되는 Background Service가 많아질수록 기기의 한정된 리소스(ram)에 대한 부담과 System에 부하가 걸리기에 Android 8.0(API 26)이상부터 사용자 환경 개선을 위해 Background 실행에 여러 제약을 두었다. 굳이 사용하겠다면 JobScheduler 혹은 WokrManager를 통해 대응을 해줘야 한다.
백그라운드 실행 제한 | Android 개발자 | Android Developers
Android 8.0 이상을 대상으로 하는 앱에 대한 새로운 백그라운드 제한.
developer.android.com
3) Bound 유형
Bound Service는 다른 Process(Component를 포함) or Service에서 Bound Service를 사용하고 싶다는 요청에 의해 실행된다.
이는 Service 자체가 다른 Process에 API를 제공한다고 보면 된다. 이에 따라 상호작용을 하게되고 결괏값을 return 받을 수 도 있게 된다.
위와 같이 System은 Bound Service의 Process와 다른 Process 사이에 종속된 관계가 있는지를 알 수 있다.
Process A가 Process B의 Service에 바인딩 되어있을 경우 System은 Process A를 위해 Process B의 Service를 실행해야 한다는 것을 인식하게 되며 이와 같은 Bound 상황일 경우 사용자가 Process A에 Focus가 맞춰있다면 Process B에도 Process A와 같은 레벨로 Focus로 맞추어지게 된다.
만약 여러개의 Component가 하나의 Bound Service에 묶여있다가 모든 곳에서 Bound Service가 해제되면 모든 Component의 해당 Service는 사라지게 된다. 이 말은 하나의 Component에서라도 Service와 Bound 되어있는 경우에는 System에서는 Service 중단을 하지 않는다.라는 의미와 같다.
Service 주의 사항
- Service는 Hosting Process의 Main Thread에서 실행되며 Service는 Thread를 직접 생성하지 않으며 별도로 지정하지 않는한 특정 Process에서 실행되지 않는다.
Service Component의 목적은 Application이 Background에서 계속 실행되지 위함이나 기본적으로 별도의 Thread를 생성하지 않고 Main Thread에서 실행되기에 Service가 CPU에 부하를 가하는 작업을 할 경우에 새로운 Thread를 생성하여 작업을 실행하도록 작성해야 한다. 그렇지 않으면 기본적으로 Main Thread에서 작업을 하게 되므로 5초 이상 지나게 될 경우 ANR Error가 발생하여 앱이 종료될 수 있음을 알아야 한다. (그냥 Service를 실행할 때에 Thread를 별도로 지정하여 실행시키는 것이 맘 편할 것이다.)
Service Lifecycle
Service는 Activity Component와는 달리 Service를 실행하는 방법에 따라 Lifecycle을 다르게 가진다. 그래서 짚고 넘어가는 것이 좋다.
다음을 보자
유형 Service 생성 방법 Service 종료 방법 Start Service startService() stopSelf() , stopService() Bound Service bindService() unbindService() Start Service
다른 Component가 startService()를 Call 하면 Service가 생성되며 무기한으로 실행된다.
자체적으로 중단하는 법으로는 stopSelf()를 통해 중단하며 다른 Component에서 중단하는 법으로는 stopService()를 호출하여 중단을 시키며 Service가 중단되면 System이 Service를 소멸시킨다.
Bound Service
다른 Process(or Component)가 BindService()를 Call 하면 Service가 생성되며 Call을 요청한 Process(or Component)가 IBinder Interface를 통해 Service와 통신을 주고받는다.(위에서 언급한 Bound 유형의 특징 중 API 형태로 생각하면 편함)
Service 연결을 중단하려면 unbindService()를 Call 하여 중단시키며 모든 Process(or Component)가 Bound를 중단해야 한 System이 Service를 소멸시킨다.
startService()를 시작된 Service에 bindService()를 호출하면 해당 Service의 유형을 Bound Service 유형으로 변경할 수 있다.
이와 같은 경우는 stopService() or stopSelf()로 Service를 중단하는 것이 아닌 unbindService()로 중단을 시켜줘야 한다.
각 service 생명주기 (악필이다 증말..) 'Android' 카테고리의 다른 글
Android Standby Bucket (0) 2022.07.01 Android - Safety Net API (에뮬레이터 감지 및 루팅 감지) (0) 2022.02.11 Component - Activity (0) 2021.10.01 scope storage 간단하게 정리 (0) 2021.07.08 정규식 (0) 2020.01.15