250704
안드로이드 앱은 단순히 하나의 main()
함수가 있는 프로그램이 아니라, 여러 개의 독립적이면서도 유기적으로 연결된 Componets의 조합이다.
따라서 시스템이나 사용자가 앱에 진입하고자 할 때, 하나의 고정된 entry point가 있는게 아니라, 상황에 따라 각 컴포넌트들이 적절한 진입점 역할을 한다.
안드로이드 4대 컴포넌트는 Activity
, Service
, Background receiver
, Content provider
로, 이들은 고유의 수명 주기를 갖는 독립적인 요소들이지만 서로에게 의존하기도 한다.
아래에서 각각에 대해 더 자세히 알아보자.
(1) Activity
사용자와 상호작용하기 위한 진입점
- 하나의 화면 단위를 의미
- UI가 있는 유일한 앱 컴포넌트
- 여러 액티비티는 서로 독립적이지만 하나의 앱을 위한 UX를 구성하기 위해 함께 동작함
(2) Service
백그라운드 실행을 위한 범용 진입점
Started Service
: 독립적으로 작동해 작업이 끝날 때까지 계속 실행되므로 명시적으로 종료해줘야 함Foreground Service
: 사용자가 인식할 수 있는 서비스로, 쉽게 죽지 않도록 시스템이 우선순위를 높게 두며,Notification
을 항상 띄움 (ex: 음악 재생)Background Service
: 사용자가 인식하지 않는 서비스로, 필요할 경우 시스템이 프로세스를 종료할 수 있음 (ex: 자동 백업)
Bound Service
: 다른 컴포넌트 혹은 앱이 서비스를 직접 제어하는 구조로, 호출자가 죽으면 서비스도 같이 종료됨 (ex: 다운로드 상태 보여주거나 취소하는 등의 기능 제공)
(3) Broadcast Receiver
User flow 밖의 이벤트가 들어오는 진입점
- 사용자 UI 흐름과 무관하게 시스템 또는 다른 앱에서 발생한 이벤트를 앱에 전달하는 역할
- 앱이 백그라운드에 있거나 꺼져 있어도 시스템이 이벤트를 감지하고 앱 내부 코드가 자동으로 실행될 수 있도록 함
- 직접 무거운 작업을 하지는 않고, 주로 다른 컴포넌트를 호출하여 연결해주는 게이트웨이 역할을 함
설명처럼, 브로드캐스트 리시버에서는 “신호만 받고, 진짜 일은 위임” 하는 구조가 권장된다. 그럼 진짜 일은 누가 할까?
JobScheduler
를 통해 JobService
를 예약하고, 실제로 무거운 작업은 JobService
에서 수행한다.
(4) Content provider
데이터를 다른 앱이나 시스템이 접근할 수 있게 만드는 진입점
- 다른 앱이 파일, DB 등의 데이터를 조회/수정 가능하게 연결해주는 중간 통로 역할
- URI를 통해 데이터에 이름을 붙여주므로, 앱이 죽어도 URI는 남아있고, 시스템은 필요할 때 앱을 깨워서 데이터를 가져올 수 있음
- 민감한 데이터를 직접 노출하지 않고, URI를 통해 필요한 데이터만 선택적으로 공개할 수 있음
Content provider를 제외한 세 가지 컴포넌트들은 모두 Intent
를 통해 활성화된다.
Intnet: 메세지를 전달해서 컴포넌트를 실행시키는 비동기 메시지 객체
- Explicit Intent: 실행할 컴포넌트(클래스 이름)를 명확히 지정함
- Implicit Intent: 수행할 action만 정의하고, 어떤 컴포넌트가 받을지는 시스템이 판단함
- 주로
Bundle
을 통해 데이터 전달
반면 Content provider는 통신하기 위한 전용 API인 ContentResolver
를 이용한다.
- URI 기반으로 데이터 요청(query), 삽입(insert), 삭제(delete), 업데이트(update) 가능
- Intent에서 Bundle이 목적지, 행동 등을 담는다면 ContentResolver에서 URI는 수정할 데이터의 주소 역할을 함
그리고 이 모든 컴포넌트들은 AndroidManifest.xml
파일에 선언되어야 한다.
매니페스트 파일은 안드로이드 앱의 구조, 권한, 구성 요소들을 정의하는 필수 설정 파일로, 쉽게 말하면 시스템이 앱을 실행하기 전에 앱의 정보를 읽을 수 있는 유일한 공식 문서다. 따라서 시스템은 이 매니페스트 파일을 기준으로 앱을 해석하고 컴포넌트를 실행한다.
+) 컴포넌트를 등록하지 않으면 ActivityNotFoundException
등이 발생할 수 있다.