컴포넌트는 시스템에 의해 생명주기가 관리되며, 앱에서 독립적으로 실행 될 수 있는 구성 단위입니다. 안드로이드에서 가장 기본이 되는 개념이라고 해도 과언이 아닐 만큼 중요한 개념입니다.
안드로이드의 컴포넌트는 Activity
Service
Content Provider
Boradcast Receiver
이렇게 네 가지로 구성되며, Intent
를 통해 상호작용 합니다.
컴포넌트를 사용하기 위해선 Android Manifest.xml
에 사용하고자 하는 컴포넌트를 등록해야합니다.
많이들 혼동하시는 개념이 있는데, 안드로이드에는 앞서 말씀드린 컴포넌트 이외에도 다양한 구성요소들이 있습니다. 이를테면
Dialog
Fragment
같은 개념이 되겠네요.그러나 이와 같은 요소들은 컴포넌트가 아닙니다. 컴포넌트는 안드로이드에서 인텐트를 통해 통신하는 독립적인 실행이 가능한 구성 단위라고 정의하고 있으며,
Dialog
Fragment
는 그 자체적으로 실행 가능한 단위가 아니라,Activity
에 의존해서 실행 되는 '하위 종속'의 관계이기 때문입니다.
액티비티는 사용자가 어플리케이션과 상호작용하는 단일 화면, 즉 인터페이스입니다. 모든 안드로이드 어플리케이션은 반드시 하나 이상의 액티비티를 포함하고 있으며, 이 액티비티의 LifeCycle
내에서 사용자가 원하는 기능들을 수행할 수 있습니다.
액티비티는 다음과 같은 특징을 갖습니다.
서비스는 백그라운드에서 장시간 실행되어야 할 작업이 있을 때 사용합니다. 메인 스레드에서 수행되며, 액티비티와는 다르게 별도의 UI가 존재하지 않습니다. 액티비티에서 실행 된 스레드의 경우, 앱이 종료되는 시점에 같이 사라지게 되지만, 서비스는 서비스를 호출 한 앱이 종료되어도 백그라운드에 남아 할당 된 업무를 계속해서 수행합니다.
서비스는 세 가지 유형으로 나뉩니다.
백그라운드에서 수행 할 작업을 수행하되, 상단에 notification
을 제공하여 사용자가 수행 되는 서비스에 대해 인지 할 수 있도록 합니다. 포그라운드 서비스를 시작했음에도 notification
을 시스템에 등록하지 않으면 5초 뒤 ANR(Android Not Response)
상태가 됩니다.
백그라운드 서비스 실행 제한
에 대한 솔루션으로 제안되었으나, 최신 API 31(Android 12.0)에선 더 이상 백그라운드에서 포그라운드 서비스를 실행 할 수 없습니다. 백그라운드에 관련 된 작업은WorkManager
를 사용하도록 권장합니다 (관련 링크)
사용자에게 직접 보이지 않는 작업을 수행합니다.
API 26(Android8.0)이상의 환경에선 앱이 포그라운드에 있지 않을 때
백그라운드 서비스 실행 제한
이 적용됩니다.때문에 꼭 백그라운드에서 수행되어야 한다면
WorkManager
를, 그렇지 않다면Foreground Service
의 사용을 고려해야합니다.
startService()
를 통해 실행 되는 다른 서비스와는 다르게 bindService()
를 통해 시작되며, 클라이언트-서버 인터페이스
를 제공하여 액티비티와 데이터를 주고 받을 수 있습니다.
연결 된 액티비티가 모두 사라지면 서비스도 소멸하게 됩니다.
브로드캐스트 리시버는 별도의 UI 없이 안드로이드 OS로부터 발생하는 각종 이벤트와 정보를 받아와 처리하는 컴포넌트입니다.
Sleep&Awake
네트워크 연결 단절
SMS 도착
배터리 부족 알림
타 앱에서 보내는 브로드캐스트
등을 처리 합니다.
이러한 메세지를 받았을 때, 그에 맞는 처리를 하기 위해 브로드캐스트 리시버
를 구현합니다.
컨텐트 프로바이더는 해당 앱 내에서 사용하는 Local-Sqlite DB
를 다른 앱과 공유하기 위해 사용합니다. 데이터 공유를 위한 표준 인터페이스로 query
insert
update
delete
를 제공합니다.
컨텐트 프로바이더가 공유하는 데이터를 사용하기 위해선 Content Resolver
를 구현해야합니다. Content Resolver
는 컨텐트 프로바이더에 정의되어 있는 표준 인터페이스를 호출하는 역할을 합니다.
인텐트는 컴포넌트 간 작업 수행을 위한 정보를 전달하는 역할을 합니다.
인텐트는 두 가지 유형이 있습니다.
실행하고자 하는 어플리케이션이 무엇인지 패키지, 클래스 단위로 정확히 지정합니다. 명시적 인텐트는 일반적으로 앱 안에서 컴포넌트를 시작할 때 사용합니다.
특정 컴포넌트를 정확히 명시하지는 않지만, 그 대신 수행 할 일반적인 작업을 전달하여 해당 동작을 수행 할 수 있는 앱을 사용자가, 혹은 시스템이 선택하여 처리할 수 있도록 할 때 사용합니다.
예를 들어 동영상을 재생하고자 할 때 필요한 동영상 플레이어를 암묵적 인텐트를 통해 실행한다면, 정확한 플레이어의 패키지를 몰라도 실행할 수 있습니다.
사용자의 환경에 동영상 플레이어 앱이 한 개가 있다면 그 앱이 즉시 실행 될 것이며, 여러 개가 있다면 여러 앱들의 목록이 뜬 뒤 사용자에게 실행 할 앱을 선택 받게 됩니다.
참고 자료
포어그라운드 서비스
바인드서비스
컨텐트 프로바이더
인텐트