티스토리 뷰

Android

[Android]Context

cherishee 2020. 2. 26. 11:51

Android : Context

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 클래스이다. 애플리케이션별 리소스와 클래스에 접근은 물론, launching activities, broadcasting, receiving intents와 같은 애플리케이션 레벨의 API 호출을 가능하게 한다.

 

즉, Context는

  1. 어플리케이션에 관하여 시스템이 관리하고 있는 정보에 접근한다

    • getPackageName(), getResource() 등의 메서드

  2. 안드로이드 시스템이 제공하는 서비스에 API를 호출하여 사용할 수 있다.

    • startActivity(), bindService() 등의 메서드

왜 Context가 필요할까?

전역적인 어플리케이션 정보에 접근하거나 연관된 시스템 기능을 수행하기 위해 필요하다. 하지만 다른 플랫폼에서는 직접 시스템 API를 호출한다. 즉, 안드로이드에서만 context 에 정의된 인스턴스 함수를 호출해야만 접근 및 사용이 가능하다.

왜 이런 차이가 있는 것일까? 즉, 다른 플랫폼에서는 어떻게 정적 함수 호출을 통해 어플리케이션에 관한 정보를 가져오고, 시스템 함수를 호출하는 것일까?

 

일반적인 경우, 어플리케이션이 프로세스와 아주 긴밀하게 연결되어 있기 때문이다. OS 커널의 가장 중요한 일 중 하나는 프로세스를 관리하는 것이다. 특정 프로세스가 특정 어플리케이션과 맵핕이 된다면, 우리는 별다른 매개체 없이 시스템에 직접 프로세스의 정보에 대해 물어보고, 시스템 함수를 호출 할 수 있다.

 

하지만 안드로이드에서 어플리케이션과 프로세스의 관계는 좀 다르다. 안드로이드에서 어플리케이션과 프로세스는 서로 독립적으로 존재한다. 예를 들자면, 안드로이드 플랫폼에서 프로세스가 없는 상황에도 어플리케이션은 살아있는 것처럼 사용자에게 표시되기도 하고, 메모리가 부족한 상황이 될 경우, 작동중이던 프로세스가 강제로 종료되고 대신 해당 프로세스에서 작동중이던 어플리케이션 관한 일부 정보만 별도로 관리하고, 이 후에 메모리 공간이 확보되면 저장되어있던 어플리케이션 정보를 바탕으로 새로운 프로세스를 시작하는 일이 벌어진다.

 

안드로이드에서도 프로세스는 당연히 OS 커널에서 관리된다. 어플리케이션과 프로세스가 별도로 관리되고 있다면, 어플리케이션 정보는 어디에서 관리하고 있을지 의문이 든다. 안드로이드의 시스템 서비스 중 하나인 ActivityManagerService에서 그 책임을 진다.

그렇다면 ActivityManagerService는 어떤식으로 어플리케이션을 관리하고 있을까? 특정 토큰을 키 값으로 'key-valule' 쌍으로 이루어진 배열을 이용하여 현재 작동중인 어플리케이션 정보를 관리한다.

 

Context는 어플리케이션과 관련되 정보에 접근하고자 하거나 어플리케이션과 연관된 시스템 레벨의 함수를 호출하고자 할 때 사용된다. 그런데 안드로이드 시스템에서 어플리케이션 정보를 관리하고 있는 것은 시스템이 아닌 ActivityManagerService 라는 일종의 또 다른 어플리케이션이다. 따라서 다른 일반적인 플랫폼과는 달리, 안드로이드에서 어플리케이션과 관련된 정보에 접근하고자 할때는 ActivityManagerService를 통해야만 한다. 당연히 정보를 얻고자 하는 어플리케이션이 어떤 어플리케이션인지에 관한 키 값도 필요하다.

즉, 안드로이드 플랫폼상에서의 관점에서 살펴보면, Context는 두가지 역할을 수행하기 때문에 필요하다.

  1. 자신이 어떤 어플리케이션을 나타내고 있는지 알려주는 ID 역할

  2. ActivityManagerService 에 접근할 수 있도록 하는 통로 역할

정리하면 다음과 같다.

일반 OS 플랫폼에서 어플리케이션은 곧 프로세스이다. 특정 어플리케이션이 OS에게 내가 어떤 프로세스인지 알려주면 어플리케이션 관련된 정보를 얼마든지 획득할 수 있다. 따라서 context와 같은 애매한 중간 매개체가 존재할 이유가 없다.

하지만 안드로이드는 다르다. 특정 어플리케이션이 자신이 본임임을 확인 받을 수 있는 방법은 자신이 작동중인 프로세스를 보여주는 것이 아니라 , 자신이 건내받은 ID카드를 제시하는 것이다. ㅣ이 때 ID카드의 역할을 수행하는 것이 바로 context이고, 위변조가 가능하기 때문에 자신의 권한을 제 3의 어플리케이션에게 넘겨주는 PendingIntent와 같은 기능도 가능해진다.

Context는 언제 태어날까?

어플리케이션이 태어날 때이다. 그렇다면 하나의 어플리케이션을 구성하는데 각종 컴포넌트 - Activity, Service, BroadcastReceiver 들은 모두 동일한 Context를 공유해서 사용하고 있을까?? 그렇지 않다.

 

Activity 와 Service가 생성될 때 만들어지는 context와 BroadcastReceiver가 호출될 때 전해지는 context는 모두 다른 인스턴스이다. 즉, context는 어플리케이션이 시작될 때는 물론, 컴포넌트들이 생성될때마다 생성된다.

 

그렇다면 왜 context 인스턴스를 공유하지 않고 모두 서로 다른 인스턴스를 만들어 사용하고 있나? Context 의 기능 중, 시스템 API 를 호출하는 기능과 관련되어 한 가지 문제점이 있다. 어떤 어플리케이션 컴포넌트가 시스템 API를 호출하느냐에 따라서 서로 다른 결과가 나타나야 한다는 점이다. 예를들어, 동일한 형태로 startActivity 메서드 호출하더라도, 일반적인 Activity 에서는 정상적으로 새로운 Activity 를 시작하게 되지만, Service 에서 호출할 경우에는 예외가 발생한다. 만일 어플리케이션을 구성하는 Service 와 Activity 가 서로 동일한 Context 인스턴스를 공유하고 있다면 동일한 메서드 호출에 대하여 서로 다른 결과를 나타내도록 구현하지 못했을 것이다.

 

출처 : http://blog.naver.com/PostView.nhn?blogId=huewu&logNo=110085457720


부록 : Application Context VS Activity Context

  • 어떠한 Context를 Scope이 더 큰 Context나 어떤 무언가가 참조하고 있으면 GC 되지 않고 많은 메모리를 잃게 되므로 조심하지 않으면 메모리 누수가 쉽게 발생할 수 있다.

Application Context

  • 어플리케이션과 관련된 것이며 어플리케이션이 살아있는 동안 변경되지 않는다. (싱글톤)

  • getApplicationContext()를 통해 Activity에서 접근할 수 있는 인스턴스이다.

  • 생명주기와 관련되어있기 때문에 현재 Context와 분리된 어떤 Context가 필요하거나 현재 Activity Scope을 벗어난 작업을 할 때 사용한다.

  • 어떤 싱글톤 객체를 만들어야하고 해당 객체에 항상 Context가 필요한 경우에 Application Context를 전달하면 된다.

  • Application Context에 Activity를 참조하게 되면 Activity가 없어지더라도 참조가 유지되므로, Activity가 GC(가비지 콜렉팅)되지 않으므로 메모리 누수가 발생한다.

  • 다른 Context보다 가장 오래 보존될만한 Context가 필요할때만 getApplicationContext()를 사용한다.

  • Application Context로는 대부분 GUI(화면, View, 등) 작업은 할 수 없다. (Activity만 가능)

Activity Context

  • 액티비티와 관련이 있다. 액티비티가 사라지면 context도 같이 사라진다.

  • 예를 들어 새로운 액티비티를 실행한다면, 액티비티(컨텍스트)가 필요하다.

  • 새로 띄워진 액티비티는 이전 액티비티와 연관되어져 액티비티 스택에 보관된다.

    Application Context를 이용하여 새로운 액티비티를 띄울수도 있지만 그럴경우 반드시 Intent.FLAG_ACTIVITY_NEW_TASK 플래그를 설정 해야한다.

출처 : https://www.charlezz.com/?p=1080

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함