본문 바로가기

어플리케이션 구성

안드로이드 어플리케이션의 구성요소

안드로이드 어플리케이션을 만들기 전에 안드로이드 어플리케이션은 과연 어떤 구조를 가지고 있을까? 에 대해서 알아보도록 하겠습니다. 

안드로이드 어플리케이션이 어떤 구조를 가지고 있는지 알고 있어야만 앞으로 진행할 강좌도 무리없이 소화할 수 있고, 무엇보다도 처음부터 어느 정도의 기본 바탕을 잡고 공부를 하면 앞으로 배우는 것들을 이해하는 속도도 빠르고, 좀 더 머릿속에 체계적으로 정리할 수 있기 때문에 좀 지루한 감이 있더라도 잘 읽고 이해하도록 해 주세요.  


가능하다면 그냥 외우세요! 정말 중요한겁니다!!


안드로이드 어플리케이션의 구성 요소는 다음과 같이 사용자가 직접 눈으로 보며 상호작용을 하는 컴포넌트(액티비티, 알림;Notification)와 사용자의 눈으로 볼 수 없거나 백그라운드에서 실행되는 컴포넌트(컨텐트 프로바이더, 서비스, 브로드캐스트 리시버)로 나눌 수 있습니다. 사실 인텐트(Intent)와 Notification은 어플리케이션 컴포넌트라고 할 수 없지만, 각 컴포넌트들과 깊은 연관을 가지고 있기에 여기에서 함께 다뤄보도록 하겠습니다.



어플리케이션을 구성하는 컴포넌트는 액티비티, 컨텐트 프로바이더(Content Provider), 서비스(Service), Broadcast Receiver가 있습니다. 어플리케이션은 이들 컴포넌트 중 여러 컴포넌트로 구성되며, 각 구성요소를 사용하기 위해서는 각 구성요소를 호출해야 하는데, 이를 위해 인텐트(Intent)를 사용합니다. 

인텐트도 어플리케이션 내에 포함되는것이 아니냐? 할 수도 있지만, 엄연히 따지면 "인텐트" 자체는 어플리케이션 컴포넌트들을 호출해 주는 역할을 할 뿐, 어플리케이션 내에 존재한다고 보기는 어렵습니다. 하지만, 각 컴포넌트가 호출될 수 있는 조건을 담고 있는 인텐트 필터(Intent-Filter)는 해당 각 컴포넌트 내에 존재합니다. 이 글에서는 어플리케이션의 '얼굴' 역할을 하는 액티비티에 대해 자세히 알아보도록 하겠습니다. 인텐트 및 인텐트 필터에 관련된 내용은 아래의 글들을 참고하세요.



액티비티(Activity)
는 어플리케이션의 "한 화면"을 뜻합니다, 전화번호부 어플리케이션을 예로 들자면 전화번호부를 조회하는 화면, 전화번호를 새로 추가하는 화면, 입력된 데이터를 수정하는 화면 등등이 하나의 액티비티가 됩니다.

전화번호부 조회 화면

전화부 편집 화면

전화부 선택 화면


액티비티는 어플리케이션 컴포넌트 중 가장 중요한 역할, 사용자의 입력을 받고 사용자에게 그 결과를 보여주는 등 실질적으로 사용자와 상호작용을 하는 역할을 맡고 있습니다. 따라서, 액티비티 구성은 어플리케이션 개발에서 가장 신경써야 할 부분이기도 합니다.

기본적으로 안드로이드가 휴대용 기기에서 돌아가는 것을 목적으로 하는 플랫폼이다보니, PC와 비교해 메모리가 부족할 수 밖에 없습니다. 그러다보니, 한 번에 여러 가지의 작업을 하다가 메모리가 부족해지면 우선순위가 낮은 작업은 메모리를 반환하여 다른 작업을 수행할 수 있도록 합니다.

메모리 관리를 위해 액티비티는 액티비티 생애 주기(Activity Lifecycle)에 따라 사용자와 상호작용을 하지 않는 액티비티를 비활성화 시키거나 종료시킬 수 있습니다. 이러한 특성 때문에 액티비티를 구성할 때 각 액티비티의 상태변화에 따라 적절한 처리를 해주는 것이 중요합니다. 

 
서비스(Service)는 화면에 표시되며 사용자와 직접 상호작용을 하는 액티비티와는 달리, 화면에 표시되지 않고 백그라운드에서 실행되는 컴포넌트입니다.

앞서 언급했듯이, 액티비티는 액티비티 생애 주기에 의해 사용자와 상호작용을 하지 않는 액티비티는 비활성화 되거나 소멸될 수 있습니다. 예를 들면, 음악을 재생하는 어플리케이션에서 음악 재생을 담당하는 부분이 액티비티에 구현되어 있다면 액티비티가 화면에서 없어짐과 동시에 해당 액티비티는 더이상 사용자와 상호작용을 하지 못하므로 액티비티 생애주기에 따라 비활성화 상태(Inactive)가 되므로 음악 재생이 중지됩니다. 



음악을 재생하는 어플리케이션은 해당 어플리케이션이 화면에 표시되고 있지 않을 때, 즉 사용자와 상호작용을 하지 않고 있더라도 백그라운드에서 계속 음악을 재생할 수 있어야 합니다. 따라서, 일반적으로 음악 재생 어플리케이션에서 음악을 재생하는 부분은 서비스 부분에 구현하여 사용자와 상호작용이 중단되더라도 지속적으로 음악을 재생할 수 있게 합니다.


컨텐트 프로바이더(Content Provider)는 어플리케이션 내의 데이터 (전화번호부, 메모 등..)를 다른 어플리케이션과 공유할 수 있도록 해줍니다.

어플리케이션 내의 데이터들은 기본적으로 해당 어플리케이션에서만 접근할 수 있고, 다른 어플리케이션은 접근할 수 없습니다. 그래서 특정 어플리케이션 내의 데이터 (예: 전화번호부 데이터)에 다른 어플리케이션에서도 접근할 수 있게 하려면 컨텐트 프로바이더를 정의하여 다른 어플리케이션에서 해당 데이터에 접근할 수 있는 범위, 방식 등을 정의해주어야 합니다. 즉, 컨텐트 프로바이더가 어플리케이션의 데이터에 접근하는 통로가 되는 셈이죠.

일반적으로 컨텐트 프로바이더를 이용하여 데이터를 공유할 어플리케이션에서 공유를 하고 싶은 데이터만을 선택하여 공유를 할 수 있도록 지정하게 됩니다. 이 과정에서 해당 컨텐트 프로바이더로 접근할 수 있는 고유의 주소를 정의하게 되며, 컨텐트 리졸버(Content Resolver)에 이 주소를 넘겨서 공유된 데이터에 접근할 수 있습니다.



컨텐트 프로바이더는 마치 싸이월드 미니홈피와 비슷하다고 할 수 있습니다. 요즘은 사진 등을 올릴 때 최소 일촌공개로 사진을 올리는 경우가 많습니다. 물론 일촌공개인 사진 외에 자신만 볼 수 있는 비공개 사진들도 있겠구요. 즉, 일촌공개도 결국은 비공개인 사진 중 일부를 볼 수 있도록 공개해 주는 것이라 볼 수 있습니다. 이와 같이 컨텐트 프로바이더도 어플리케이션의 데이터에 접근할 수 있는 중재자 역할을 하며, 그 범위까지 지정해주는 역할을 수행합니다.

 
브로드캐스트 리시버(Broadcast Receiver)는 주로 시스템의 상태에 관련된 메시지 (배터리 부족, 언어 변경됨 등..) 혹은 어플리케이션의 메시지 (파일 다운로드 완료 등..)에 응답하는 역할을 합니다. 브로드캐스트 리시버는 해당 이벤트가 발생하였을 경우 그를 잡아내는 능력만 있을 뿐, 이를 사용자에게 알릴 방법은 없습니다. 때문에, 사용자에게 해당 이벤트를 알리기 위해 알림(Notification) 혹은 토스트(Toast)을 사용합니다.



알림(Notification)은 NotificationManager를 통해 상태 표시줄 및 Notification Panel을 통해 알림 메시지를 띄워주거나,  LED를 점멸시키거나, 진동 발생 혹은 벨소리를 울리게 하여 사용자에게 해당 이벤트를 알립니다. 이러한 알림(Notification)은문 문자메시지 도착, 다운로드 완료 등을 사용자에게 알리는 데 사용됩니다.

마지막으로, 인텐트(Intent)에 대해 알아보도록 하겠습니다.

인텐트(Intent)는 어플리케이션의 컴포넌트, 구체적으로 말하자면 액티비티, 서비스, 브로드캐스트 리시버를 호출하거나 해당 컴포넌트를 호출함과 동시에 필요한 데이터를 전달해주는 역할을 합니다. 일종의 "전달 매체"라고 하면 적절하겠네요.

인텐트 내부에는 대상 컴포넌트에 대한 정보가 담겨있습니다. 인텐트는 담고 있는 정보의 유형에 따라 명시적 인텐트(Explicit Intent)암시적 인텐트(Implicit Intent)로 나뉩니다.

명시적 인텐트(Explicit Intent)는 호출하거나 데이터를 전달한 컴포넌트가 정확히 명시되어 있는 인텐트입니다. 대상 컴포넌트가 명확할 경우 컴포넌트의 이름을 인텐트에 넣어주면 인텐트에 의해 해당 컴포넌트가 호출되거나 해당 컴포넌트에 데이터가 전달되게 됩니다.

정확한 주소가 나와있군요!



암시적 인텐트(Implicit Intent)는 호출하거나 데이터를 전달할 컴포넌트를 정확히 명시하지 않고, 대상 컴포넌트의 특징들만 나열한 인텐트입니다. 예를 들면, 메모를 수정하는 인텐트에는 메모를 수정하는 기능을 가진 컴포넌트의 이름이 아닌 [메모를 수정할 수 있는 기능]이 들어가게 됩니다.


목적지의 특성이 나열되어있군요



이러한 암시적 인텐트를 처리하려면 각 컴포넌트에 해당 컴포넌트가 처리할 수 있는 작업을 명시해주어야 호출 대상 컴포넌트가 인텐트를 받아 호출될 수 있습니다. 이렇게 인텐트를 해석하여 적절한 컴포넌트를 찾는 과정을 인텐트 해석(Intent resolving)이라 합니다. 인텐트 해석(Intent resolving)에 필요한 정보는 메니페스트 파일인 AndroidManifest.xml 의 각 컴포넌트 태그 내의 인텐트 필터 (Intent-filter) 내에 명시되며, 이곳에는 각 컴포넌트가 처리할 수 있는 작업의 유형 뿐만 아니라 해당 컴포넌트에서 처리할 수 있는 데이터의 유형까지 명시되어 있습니다. 메니페스트 파일에 대한 자세한 정보는 다음 글을 참고하세요.


여기까지, 어플리케이션을 이루는 6가지 구성요소에 대해 알아보았습니다.
다음 강좌에서는 실제 개발 환경에서 프로젝트를 생성하는 절차와 프로젝트 생성시 생성되는 파일들에 대해 알아보도록 하겠습니다. ^^

20091120