안드로이드/Android Context 란?
<안드로이드 Context 는 수수께기가 많은 클래스입니다>
Android Context Story
저에게 안드로이드 Context 는 참 어려운 녀석입니다. 안드로이드 어플리케이션을 개발하며서 가장 빈번하게 사용되는 클래스 중 하나인건 분명한데, 지나가는 사람이 Context 가 뭔가요? 라고 물어 본다면, 스스로가 만족할 만큼 속 시원하게 대답할 수 있는 부분이 없습니다.
관련해서 이런 저런 자료를 뒤져보고, 잘 읽히지도 않는 안드로이드 소스도 살펴보곤 했습니디만, 이거다... 라고 확실하게 짚고 넘어갈 건데기를 건져내지는 못했습니다. 그저 스스로에게 던진 질문 (안드로이드 Context 는 뭐지?)에 대한 나름의 대답이라는 의미로, 아는 한도내에서 Context 의 기능, Context 가 필요한 이유 그리고 Context 는 어떻게 태어나서 어떻게 사라지는지 정리해 봅니다.
Context 가 뭐지?
우선은 정석대로. 안드로이드 개발자 사이트의 Context 클래스 오버뷰 내용을 살펴 봅니다.
Class OverviewInterface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc.
어플리케이션 환경에 관한 글로벌 정보를 접근하기 위한 인터페이스. Abstract 클래스이며 실재 구현은 안드로이드 시스템에 의해 제공된다. Context 를 통해, 어플리케이션에 특화된 리소스나 클래스에 접근할 수 있을 뿐만 아니라, 추가적으로, 어플리케이션 레벨의 작업 - Activity 실행, Intent 브로드캐스팅, Intent 수신 등, 을 수행하기 위한 API 를 호출 할 수도 있다.
즉, Context 는 크게 두 가지 역할을 수행하는 Abstract 클래스 입니다.어플리케이션에 관하여 시스템이 관리하고 있는 정보에 접근하기
안드로이드 시스템 서비스에서 제공하는 API 를 호출 할 수 있는 기능
Context 인터페이스가 제공하는 API 중, getPackageName(), getResource() 등의 메서드들이 첫 번째 역할을 수행하는 대표적인 메서드입니다. 보통 get 이라는 접두어로 시작하는 메서드들이지요. 그 외에, startActivity() 나 bindService() 와 같은
메서드들이 두 번째 역할을 수행하기 위한 메서드라고 할 수 있습니다.
왜 Context 가 필요할까?
음... Context 의 기능은 대충 알만합니다. Context 와 관련되서 보다 곤란한 질문은 'Context 가 왜 필요하지?' 라고 생각합니다. 전역적인 어플리케이션 정보에 접근하거나 어플리케이션 연관된 시스템 기능을 수행하기 위해, 시스템 함수를 호출하는 일은 안드로이드가 아닌 다른 플랫폼에서도 늘상 일어나는 일입니다. 또, 그런 일들은 대게의 경우 (제가 아는한...) 어떠한 매개체를 거칠 필요없이, 직접적으로 시스템 API 호출하면 됩니다. 반면 안드로이드에서는 Context 라는 인스턴스화된 매개체를 통해야만 유사한 일들을 수행할 수 있습니다.
예를 들어, C# 에서 어플리케이션 이름을 가져오고, 다른 어플리케이션을 실행시키는 코드는 아래와 같이 작성될 수 있습니다. //Get an Application Name. String applicationName = System.AppDomain.CurrentDomain.FriendlyName;
//Start a new process(application) System.Diagnostics.Process.Start("test.exe");
반면에 안드로이드 Activity 에서는 아래와 같이 작성 해야 됩니다.//Get an application nameString applicationName = this.getPackageName();
//Start a new activity(application)this.startActivity(new Intent(this, Test.class));
보시는 것 처럼, C# 의 경우 System 단에서 제공하는 정적 함수(static function)를 호출 함으로서 간단하게 할 수 있는 일들을 안드로이드에서는 Context 에 정의된 인스턴스 함수를 호출해야만 가능하게 되어있습니다. 즉, 위에서 처럼 반드시 인스턴스화된 Context 클래스(여기서는 this) 를 사용해야 되는 셈이지요.
왜 이런 차이가 생기게 된걸까요?
대답하기 애매한 질문인 경우에, 질문을 거꾸로 뒤짚어 보면 서광이 비치는 경우가 있습니다. 안드로이드가 아닌 플랫폼에서는 어떻게 정적 함수 호출을 통해서 어플리케이션에 관한 정보를 가져오고, 시스템 함수를 호출 할 수 있는 걸까요?
제가 OS 에 관한 지식이 짧아, 꼭 찝어 이야기하기에는 어려움이 있지만... 일반적인 경우, 어플리케이션이 프로세스가 아주 긴밀하게 연결되어 있기 때문입니다. OS 커널의 가장 중요한 일 중 하나는 프로세스를 관리하는 것 입니다. (아마도..) 특정 프로세스가 특정 어플리케이션과 맵핑 된다면, 우리는 별다른 매개체 없이 시스템에 직접 프로세스의 정보에 관한 물어 볼 수 있고, 프로세스와 연관된 시스템 함수를 호출 할 수 있습니다. (이미 관리하고 있는 정보에 대해 묻고 있음으로)
그런데 안드로이드에서 어플리케이션과 프로세스와의 관계는 조금 요상한 구석이 있습니다. 안드로이드에서 어플리케이션과 프로세스는 서로 독립적으로 존재입니다. 이와 관련된 구체적인 내용이나 이러한 구조를 갖는 원인에 대해서는 안드로이드 멀티태스킹에 관한 구글 개발자 블로그 포스트 에서 자세하게 다루어져 있습니다. (블로그에 번역해 두었으니 꼭 한번 읽어 보세요.)
예를 들자면, 안드로이드 플랫폼에서는 프로세스가 없는 상황에도 어플리케이션은 살아있는 것처럼 사용자에게 표시되기도 하고, 메모리가 부족한 상황이 될 경우, 작동중이던 프로세스가 강제로 종료되고, 대시 해당 프로세스에서 작동중이던 어플리케이션에 관한 일부 정보만 별도로 관리하고, 이 후에 메모리 공간이 확보되면 저장되어있던 어플리케이션 정보를 바탕으로 새로운 프로세스를 시작하는등의 신기한 일이 벌어집니다.
안드로이드에서도 프로세스는 당연히 OS 커널 (리눅스)에서 관리됩니다. 어플리케이션과 프로세스가 별도로 관리되고 있다면, 어플리케이션 정보는 어디에서 관리하고 있을까요? 안드로이드의 시스템 서비스 중 하나인 ActivityManagerService 에서 그 책임을 집니다. 그렇다면 ActivityManagerService 는 어떤식으로 어플리케이션을 관리하고 있을까요? 이외로 단순 합니다. 특정 토큰을 키값으로 'Key-Value' 쌍으로 이루어진 배열을 이용해 현재 작동중인 어플리케이션 정보를 관리합니다.
거의 결론에 다다른거 같습니다. Context 는 어플리케이션과 관련된 정보에 접근하고자 하거나 어플리케이션과 연관된 시스템 레벨의 함수를 호출하고자 할 때 사용됩니다. 그런데 안드로이드 시스템에서 어플리케이션 정보를 관리하고 있는 것은 시스템이 아닌, ActivityManagerService 라는 일종의 또 다른 어플리케이션입니다. 따라서 다른 일반적은 플랫폼과는 달리, 안드로이드에서는 어플리케이션과 관련된 정보에 접근하고자 할때는 ActivityManagerService 를 통해야만 합니다. 당연히 정보를 얻고자 하는 어플리케이션이 어떤 어플리케이션인지에 관한 키 값도 필요해집니다.
즉, 안드로이드 플랫폼상에서의 관점으로 샆펴보면, Context 는 다음과 같은두 가지 역할을 수행하기 때문에 꼭 필요한 존재입니다.
Android Context Story
저에게 안드로이드 Context 는 참 어려운 녀석입니다. 안드로이드 어플리케이션을 개발하며서 가장 빈번하게 사용되는 클래스 중 하나인건 분명한데, 지나가는 사람이 Context 가 뭔가요? 라고 물어 본다면, 스스로가 만족할 만큼 속 시원하게 대답할 수 있는 부분이 없습니다.
관련해서 이런 저런 자료를 뒤져보고, 잘 읽히지도 않는 안드로이드 소스도 살펴보곤 했습니디만, 이거다... 라고 확실하게 짚고 넘어갈 건데기를 건져내지는 못했습니다. 그저 스스로에게 던진 질문 (안드로이드 Context 는 뭐지?)에 대한 나름의 대답이라는 의미로, 아는 한도내에서 Context 의 기능, Context 가 필요한 이유 그리고 Context 는 어떻게 태어나서 어떻게 사라지는지 정리해 봅니다.
Context 가 뭐지?
우선은 정석대로. 안드로이드 개발자 사이트의 Context 클래스 오버뷰 내용을 살펴 봅니다.
Class Overview Interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc. 어플리케이션 환경에 관한 글로벌 정보를 접근하기 위한 인터페이스. Abstract 클래스이며 실재 구현은 안드로이드 시스템에 의해 제공된다. Context 를 통해, 어플리케이션에 특화된 리소스나 클래스에 접근할 수 있을 뿐만 아니라, 추가적으로, 어플리케이션 레벨의 작업 - Activity 실행, Intent 브로드캐스팅, Intent 수신 등, 을 수행하기 위한 API 를 호출 할 수도 있다. |
어플리케이션에 관하여 시스템이 관리하고 있는 정보에 접근하기
안드로이드 시스템 서비스에서 제공하는 API 를 호출 할 수 있는 기능
Context 인터페이스가 제공하는 API 중, getPackageName(), getResource() 등의 메서드들이 첫 번째 역할을 수행하는 대표적인 메서드입니다. 보통 get 이라는 접두어로 시작하는 메서드들이지요. 그 외에, startActivity() 나 bindService() 와 같은
메서드들이 두 번째 역할을 수행하기 위한 메서드라고 할 수 있습니다.
왜 Context 가 필요할까?
//Get an Application Name.String applicationName = System.AppDomain.CurrentDomain.FriendlyName;//Start a new process(application)System.Diagnostics.Process.Start("test.exe");
//Get an application nameString applicationName = this.getPackageName();//Start a new activity(application)this.startActivity(new Intent(this, Test.class));
그런데 안드로이드에서 어플리케이션과 프로세스와의 관계는 조금 요상한 구석이 있습니다. 안드로이드에서 어플리케이션과 프로세스는 서로 독립적으로 존재입니다. 이와 관련된 구체적인 내용이나 이러한 구조를 갖는 원인에 대해서는 안드로이드 멀티태스킹에 관한 구글 개발자 블로그 포스트 에서 자세하게 다루어져 있습니다. (블로그에 번역해 두었으니 꼭 한번 읽어 보세요.)
예를 들자면, 안드로이드 플랫폼에서는 프로세스가 없는 상황에도 어플리케이션은 살아있는 것처럼 사용자에게 표시되기도 하고, 메모리가 부족한 상황이 될 경우, 작동중이던 프로세스가 강제로 종료되고, 대시 해당 프로세스에서 작동중이던 어플리케이션에 관한 일부 정보만 별도로 관리하고, 이 후에 메모리 공간이 확보되면 저장되어있던 어플리케이션 정보를 바탕으로 새로운 프로세스를 시작하는등의 신기한 일이 벌어집니다.
안드로이드에서도 프로세스는 당연히 OS 커널 (리눅스)에서 관리됩니다. 어플리케이션과 프로세스가 별도로 관리되고 있다면, 어플리케이션 정보는 어디에서 관리하고 있을까요? 안드로이드의 시스템 서비스 중 하나인 ActivityManagerService 에서 그 책임을 집니다. 그렇다면 ActivityManagerService 는 어떤식으로 어플리케이션을 관리하고 있을까요? 이외로 단순 합니다. 특정 토큰을 키값으로 'Key-Value' 쌍으로 이루어진 배열을 이용해 현재 작동중인 어플리케이션 정보를 관리합니다.
거의 결론에 다다른거 같습니다. Context 는 어플리케이션과 관련된 정보에 접근하고자 하거나 어플리케이션과 연관된 시스템 레벨의 함수를 호출하고자 할 때 사용됩니다. 그런데 안드로이드 시스템에서 어플리케이션 정보를 관리하고 있는 것은 시스템이 아닌, ActivityManagerService 라는 일종의 또 다른 어플리케이션입니다. 따라서 다른 일반적은 플랫폼과는 달리, 안드로이드에서는 어플리케이션과 관련된 정보에 접근하고자 할때는 ActivityManagerService 를 통해야만 합니다. 당연히 정보를 얻고자 하는 어플리케이션이 어떤 어플리케이션인지에 관한 키 값도 필요해집니다.
즉, 안드로이드 플랫폼상에서의 관점으로 샆펴보면, Context 는 다음과 같은두 가지 역할을 수행하기 때문에 꼭 필요한 존재입니다.