-
안드로이드 4대 컴포넌트안드로이드 학습/Android 기술면접 대비 2023. 8. 13. 17:19
Android 앱은 4가지의 컴포넌트로 구성되어 있다.
(1) Activity, (2) Service, (3) Broadcast Receiver, (4)Content Provider 이를 4대 컴포넌트라 부른다.
(1) Activity (액티비티):
- 안드로이드에서 화면을 관리하고 사용자가 발생시키는 다양한 이벤트를 처리하는 컴포넌트
- UI화면을 담당하는 컴포넌트
Activity 특징 :
- 인텐트(Intent)를 통해 다른 애플리케이션의 액티비티를 호출할 수 있다.
- 2개 이상의 액티비티를 동시에 Display 할 수 없다. (1개만 가능)
- 1개 이상의 View 또는 ViewGroup을 포함한다.
- 반드시 애플리케이션에는 하나 이상의 액티비티가 있어야 한다.
- Activity 내에 프래그먼트(Fragment)를 추가하여 화면을 분할시킬 수 있다.
View와 ViewGroup이란 : 참고 링크
(2) Service (서비스):
- Service는 백그라운드 작업을 위한 애플리케이션 구성 요소이다. 사용자와 직접적으로 상호작용 X
- Service의 독자적인 생명주기를 가지고 있다 그래서 사용자가 다른 애플리케이션으로 전환하더라도 Service는 백그라운드에서 계속해서 실행된다.
- (예 : 전화 앱을 켜놓지 않은 상태에서도 전화를 받을 수 있는 것은 앱을 화면에서 직접 쓰고 있지 않아도 백그라운드에서 서비스가 돌아가고 있기 때문)
- 음악을 재생, 파일 입출력, 네트워크 작업등을 처리 할 수 있다.
- Service 자체는 main thread에서 동작. 따라서 필요시 서비스 내에서 별도의 스레드를 생성하여 작업을 처리 필요
서비스에는 크게 3가지로 나뉘는데 포그라운드, 백그라운드, 바운드로 나뉜다.
a) Foreground Service
- 알림을 표시해 놓고 사용자와 상호 작용하지 않아도 계속 실행.
- 명시적인 종료가 없다면 Activity와 같은 중요도이기 때문에 거의 종료 X. (앱이 종료되도 계속 실행됨 - 대신 알림으로 표시됨)
- 예를 들어, 음악 재생앱에서 노래가 켜져 있을 경우 알림을 켜서 노래의 진행상태를 보여준다.
- 코드 예제 : 링크
b) Background Service
- 백그라운드에서 사용자가 직접 알 필요가 없는 작업을 수행할 때 사용 (알림 X)
- 시스템에서 리소스가 부족할 경우 강제로 종료 당할 수도 있다.
- Android 8.0(API 레벨 26) 이후 사용자 환경(성능 저하 및 배터리 소모 문제)을 개선하기 위해 백그라운드에서 실행되면서 앱의 동작을 제한. Foreground Service와는 다르게 앱이 백그라운드로 전환되면 몇분 후 종료
- 코드 예제 : 링크
c) Bound Service
- Bound Service는 IBinder라는 앱 내에서 서비스를 사용해 간단한 클라이언트 - 서버 환경을 구성.(컴포넌트와 서비스간 상호작용)
- 예를 들면 Activity - 클라이언트 역할을 하고, 서비스 - 서버 역할을 할수 있다.
- 액티비티는 서비스에 어떠한 요청을 할수 있고, 서비스로부터 어떠한 결과를 받을수 있습니다.
- 여러 프로세스에서 같은 서비스에 바인딩하여 작업 수행 가능하며, 프로세스 간 통신 (IPC)을 수행 할 수 있다.
- 바운드 서비스는 바운드된 어플리캐이션이 살아있을 때 만 실행된다. 여러 컴포넌트들이 하나의 서비스에 동시 접근 가능하다.
- 만약 모든 컴포넌트들이 서비스를 unbind하면, 서비스는 destroyed 된다.
Service에 좀 더 자세한 내용 : 자세한 내용 링크
(3) Broadcast Receiver (브로드캐스트 리시버):
Broadcast Receiver는 시스템이나 앱 등에서 이벤트 발생시 방송을 해주는 개념입니다. 여기서 방송은 안드로이드에서의 메시지(알람) 를 여러 객체에 전달하는 것을 의미합니다.
안드로이드 공식 홈페이지 설명을 요약해보자면 broadcast receiver를 사용할 때는 크게 2가지다
- 시스템 이벤트 감지: 배터리가 방전되었거나 와이파이 연결이 변경되는 등의 시스템 이벤트를 감지하고 조치를 취할 수 았움
- 외부 앱과 통신: 다른 앱이 발생시킨 브로드캐스트 메시지를 수신하여 해당 앱과 상호 작용할 수 있습니다.
- 카카오톡에서 다른사람에게 카톡을 받았을 때 이 카톡을 카카오톡 앱에 알려줘야 한다면 브로드캐스팅으로 전달하면 됨.
- SMS 문자 메시지나 전화오는것 알림 등등
구글 Developer 사이트 : 링크
system broadcasts
System은 비행기 모드로 전환되는 것 같은 시스템 이벤트가 발생할 때 자동으로 브로드캐스트를 전송한다. 시스템 브로드캐스트는 이벤트를 수신하도록 구독한 모든 앱으로 전송.
브로드캐스트 메시지 자체는 발생한 이벤트를 식별하는 작업 문자열이 있는 Intent 객체에 래핑.
브로드캐스트 수신
앱은 두 가지 방법, 즉 매니페스트에서 선언된 수신기와 컨텍스트에 등록된 수신기를 통해 브로드캐스트를 수신할 수 있습니다.
Broadcast Receiver는 (1) manifest에 선언된 수신자와 (2) context에 등록된 수신자로 두 가지 방법으로 수신할 수 있다.
위에 용어는 공식홈페이지에 나온 용어다. 하지만 블로그들을 찾아보니
- "manifest에 선언된 수신자"를 Static(정적) Broadcast Receiver 혹은 Implicit(암시적) Broadcast Receiver라고도 하는 것 같다.
- "context에 등록된 수신자"는 Dynamic(동적) Broadcast Receiver 혹은 explicit(명시적) Broadcast Receiver라고 하는 것 같다.
manifest에 선언된 수신자 :
앱이 처음 실행될 때 시스템 패키지 매니저(system package manager)가 receiver를 등록한다. Receiver는 앱의 별도의 진입점이 됩니다. 즉, 앱이 현재 실행되고 있지 않으면 시스템에서 앱을 시작하고 브로드캐스트를 전달할 수 있습니다.
시스템은 수신하는 각 브로드캐스트를 처리하기 위한 새로운 Broadcast Receiver 구성요소 객체를 만듭니다. 이 객체는onReceive(Context, Intent) 호출이 지속되는 동안만 유효합니다. 코드가 이 메서드에서 반환되면 시스템은 구성요소가 더 이상 활성 상태가 아닌 것으로 간주합니다.
!!! 앱이 API 수준 26 이상을 타겟팅하는 경우 매니페스트를 사용하여 암시적 브로드캐스트 2 (앱을 구체적으로 타겟팅하지 않는 브로드캐스트)의 수신자를 선언할 수 없습니다. 단, 제한에서 제외되는 몇 가지 암시적 브로드캐스트는 예외입니다. 대부분의 경우 예약된 작업을 대신 사용할 수 있습니다. !!!
manifest에 선언된 수신자 특징
- AndroidManifest.xml 파일에 <receiver> 요소를 추가하여 정적으로 Broadcast Receiver를 등록.
- 한 번 등록하면 해제 불가능
- 앱이 실행 중이지 않아도 브로드캐스트 메시지를 수신 가능. 즉 종료되어 있는 앱을 실행시킬 수 있음
- 정적 리시버는 앱이 실행 중이지 않아도 메모리에 상주하여 리소스를 사용합니다. 따라서, 정적 리시버가 필요하지 않은 경우에도 계속해서 시스템 리소스를 차지하게 됩니다. 이는 앱의 성능 저하와 배터리 소모에 영향을 줄 수 있습니다. 신중 필요
context에 등록된 수신자 :
등록된 context가 유효한 동안 브로드캐스트를 수신한다.
즉 activity context로 등록하면 해당 activity가 destory 될때까지만 유효하고, application context에 등록한다면 앱이 종료 될 때까지 유효할 것이다.
context에 등록된 수신자 특징:
- AndroidManifest.xml에 Receiver에 대한 정보를 추가하지 않아도 된다.
- Receiver를 구현할 때 주로 사용하게 될 방식으로 리시버의 추가 및 삭제가 자유롭다.
- 앱이 실행 중일 때만 동작, 앱이 종료시 등록도 해제되어 동작하지 않습니다.
- 필요한 경우에만 클래스 파일에서 등록하고 해제 할수 있기 때문에, 이를 통해 리소스를 확보 가능 & 앱의 부하를 줄 일 수 있다.
- 그러나 해제를 적절히 해주지 않는다면 메모리 릭이 발생할 수 있다.
Broadcast Receiver에 대해 짧게 정리하자면,
- 목적 : 시스템 이벤트 감지와 외부 앱과 통신을 위해 사용
- 방법 : (1) manifest에 선언 (2) context로 선언
- manifest 특징 : API26 이후 제한이 생겨 사실상 사용 할 일 없을 것 같음.
- 제한의 예외 상황에서도 사용하더라도 신중!.
- context 특징 : 거의 대부분 context로 사용할 것 같음.
- 경험상 foreground service에 broadcast receiver를 사용하면 앱 실행과 상관없이 수행은 가능
Broadcast receiver 사용시 주의해야 할점 :
- 너무 많은 작업, 시간이 오래걸리는 작업 X. 처리 지연시간이 길어진 경우(10초) ANR 발생.
- 그래서 Broadcase receiver에서는 간단한 일을 처리하도록 한다
- 너무 많은 작업, 시간이 오래걸리는 작업 -> 별도의 Thread 생성해서 처리하도록 해야한다
ANR 이란?? ANR 설명
Content provider (컨텐트 프로바이더):
안드로이드 개발자 페이지에 나와있는 Content Provider 설명을 보자면,
Content Provider는 애플리케이션이 자체적으로 저장된 데이터, 다른 앱이 저장한 데이터에 대한 액세스 권한을 관리하도록 돕고 다른 앱과 데이터를 공유할 방법을 제공합니다.
즉, Content Provider는 다른 앱과 데이터 공유를 위한 컴포넌트다.
안드로이드 시스템에서는 각 앱들마다 각각의 DB를 가질 수 있다. 그리고 어플리케이션 내부의 DB는 해당 어플리케이션만 접근이 가능하다. 다른 어플리케이션에게 database가 전부 공개된다면 보안에 취약해 질 수 있기 때문이다.
하지만, 앱의 database의 접근을 완전히 막는 것도 문제가 될 수 있다. 예를 들어, 메신저 앱에서 프로필 사진을 갤러리로 부터 불러올때 혹은 전화번호를 기준으로 친구 목록을 불러올 때 등 다른 앱의 정보를 갖고 와야 하는 상황도 있을 것이다.
그래서 안드로이드 시스템은 어플리케이션 내부 DB에 대해 해당 어플리케이션만 접근 가능한 보안성과 다른 어플리케이션에서도 DB에 접근할 수 있도록 유연함을 제공하기 위해 컨텐트 'Provider class' 를 제공하는 것이다.
컨텐트 프로바이더와 컨텐트 리졸브를 통해 앱과 앱 사이에 데이터베이스를 공유하면서 직접적인 접근을 차단할 수 있다.
Content Provider Content provider 진행 흐름 :
다른 앱의 데이터를 사용하고자 하는 앱에서는 URI를 이용하여 콘텐츠 리졸버(Content Resolver) 를 통해 다른 앱의 콘텐츠 프로바이더에게 데이터를 요청한다. 요청 받은 컨텐츠 프로바이더는 URI를 확인하고 내부에서 데이터를 꺼내어 컨텐츠 리졸버에게 전달한다.
ContentProvider 클래스 :
앱에서 데이터 공유를 제공하기 위해서는 ContentProvider 클래스를 상속받는 클래스를 먼저 생성합니다.
자동으로 onCreate(), query(), insert(), delete(), update() 함수가 만들어지는데, 이것은 데이터베이스를 생각하면 쉽게 이해를 할 수 있습니다.
ContentProvider 코드
더보기class MyContentProvider: ContentProvider() { override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?): Int { } override fun getType(uri: Uri): String? { } override fun insert(uri: Uri, values: ContentValues?): Uri? { } override fun onCreate(): Boolean { } override fun query( uri: Uri, projection: Array<out String>?, selection: String?, selectionArgs: Array<out String>?, sortOrder: String? ): Cursor? { } override fun update( uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array<out String>? ): Int { } }
ContentProvider 사용 예:
- 연락처
- 전화기록
- 사진
- 오디오
- 비디오
- 데이터베이스 정보 등등
콘텐트 프로바이더 (ContentProvider) Uri란?
- ContentProvider를 이용해야 할 ContentResolver 앱에서 ContentProvider 내부의 상세한 DB 구조를 알 수 없다. 그래서 ContentResolver측은 ContentProvider가 제공한 Uri를 가지고 DB를 간단하게 접근이 가능하도록 기능을 제공한다.
'안드로이드 학습 > Android 기술면접 대비' 카테고리의 다른 글
Activity와 Fragment의 차이점 및 사용 이유 (1) 2024.01.08 Rxjava (0) 2024.01.05 Intent (인텐트) 와 Bundle (0) 2023.07.11 AAC - Databinding (0) 2023.06.21 안드로이드 Context (0) 2023.06.16