본문 바로가기

Programming/Android

[Android] Context

[Android] Context


What is Context?

  • Application 환경에 대한 전역 정보를 접근하기 위한 인터페이스
  • 추상 클래스이며 실제 구현은 Android 시스템에 의해 제공됨
  • Context를 통해 어플리케이션에 특화된 리소스나 클래스에 접근할 수 있음
  • Activity 실행, Intent Broadcasting, Intent수신 등과 같은 응용 프로그램 수준의 작업을 수행하기 위한 API를 호출

What is Role of Context?

  • 어플리케이션과 관련된 정보에 접근하거나 연관된 시스템 레벨의 함수를 호출할 때 사용
  • 안드로이드 시스템에서 어플리케이션과 관련된 정보에 접근하고자 할 때 ActivityManagerService를 통해야하는데 Context는 ActivityManagerService에서 어떤 어플리케이션인가를 구분하는 키가 됨
    (자신이 어떤 어플리케이션을 나타내고 있는지 알려주는 ID 역할)
  • ActivityManagerService에 접근할 수 있도록 하는 통로 역할

When is Created Context?

  • Activity와 Service가 생성될 때
  • BroadcastReceiver가 호출될 때(onRecieve())
  • 어플리케이션이 시작될 때는 물론, 애플리케이션 컴포넌트들이 생성될 때마다 생성됨
  • 새롭게 생성되는 Context들은 부모와 완전히 독립되어 있는 존재가 아니고 거의 비슷한 내용을 담고 있음

Kind of Context

Application Context

Application 자체의 lifecycle의 영향을 받음

Activity Context

Activity의 lifecycle과 함께 하며, onDestroy()와 함께 사라짐
Activity의 대한 환경 정보를 가지고 있음


Context Type

Application

실행중인 애플리케이션 프로세스는 Singleton Instance
Activity나 Service는 getApplication() 메소드를 통해 getApplicationContext()로 Context를 얻음
프로세스 내 동일한 Instance를 받음

Activity/Service

ContextWrapper를 상속받아 구현된 Context
프레임 워크는 Activity 또는 Service를 생성 할때 기본 Context에 필요한 정보를 wrap함
각각의 고유한 Context를 가짐

BroadcastReciever

자기 자신이 Context 자체는 아니지만, onRecieve()시 Context를 가져올 수 있는데, 이 때의 Context는 RecieverRestrictedContext이고,
registerReciever()와 bindService()는 사용할 수 없음
Reciever가 Broadcast를 처리할 때마다 새로운 Context를 생성

ContentProvider

BroadCast와 마찬가지로 자기 자신이 Context는 아님
하지만 access 후에는 getContext()를 통해 Context를 가져올 수 있음

Context Capabilities

UI와 관련된 모든 작업을 처리할 수 있는 유일한 구현은 Activity


Save Reference

Instance의 lifecycle를 넘는 객체 또는 클래스의 Context에 대한 참조 저장할 때 이슈 발생
예를 들어, Context에서 resource를 가져오거나 ContentProvider에 access하는 Singleton Instance에 Activity 또는 Service의 Context에 대한 참조를 저장할 경우

Bad Singleton

1234567891011121314151617public class CustomManager {
    private static CustomManager sInstance;
 
    public static CustomManager getInstance(Context context) {
        if (sInstance == null) {
            sInstance = new CustomManager(context);
        }
 
        return sInstance;
    }
 
    private Context mContext;
 
    private CustomManager(Context context) {
        mContext = context;
    }
}

Bad인 이유

  1. Context가 어디로부터 왔는지 알지 못함.
  2. 객체가 Activity 또는 Service가 될 경우, 참조를 보유하는 것은 안전하지 않음
  3. Singleton Instance에서 static reference로 관리되기 때문에 Instance와 Instance에 의해 참조되는 다른 모든 객체가 garbage collecter에 수집이 되지 않음
  4. Context가 Activity인 경우, 모든 view와 그 와 연관된 잠재적 객체들이 메모리에 잡혀있게 됨
  5. 누수가 발생함

Better Singleton

123456789101112131415161718public class CustomManager {
    private static CustomManager sInstance;
 
    public static CustomManager getInstance(Context context) {
        if (sInstance == null) {
            //Always pass in the Application Context
            sInstance = new CustomManager(context.getApplicationContext());
        }
 
        return sInstance;
    }
 
    private Context mContext;
 
    private CustomManager(Context context) {
        mContext = context;
    }
}

Better인 이유

  1. Context가 어디로부터 왔는지 알고 있음
  2. application context가 singleton 자체이기 때문에 reference가 안전하고, 누수도 발생하지 않게 됨

좋은 예 : 실행중인 백그라운드 스레드 또는 보류 중인 handler 내부에서 Context에 대한 참조를 저장하는 것


Context Reference

Activity.getApplicationContext()

현재 활성화된 Activity만이 아닌 어플리케이션 전체에 대한 Context가 필요한 경우

View.getContext()

현재 활성화된 Activity에 대한 Context 참조시 사용, this를 사용하는 것과 같은 맥락

ContextWrapper.getBaseContext()

어느 Context에서 다른 Context를 참조해야하는 경우 ContextWrapper 객체를 사용하는데, 그 ContextWrapper 안에 있는 Context를 참조하는 경우


Reference

안드로이드 Context 이야기 : 네이버 블로그
[Android] Context란? - 노블의 개발이야기
Context, What Context? - by Dave Smith of Double Encore
안드로이드에서 Context란 무엇일까 | Recording transience


'Programming > Android' 카테고리의 다른 글

[Android] Dalvik & ART  (1) 2019.04.16
[Android] 앱 구성 요소(Application Component)  (2) 2018.09.15
[Android] How To APK Install Programmatically  (0) 2018.09.05
[Android] Input Event  (0) 2018.06.16
[Android] View  (0) 2018.06.14