Prologue

Android에서 빼놓을 수 없는 게 있는데, 바로 Context이다.
예전에 작성했던 글이 있는데, 설명이 너무 장황하여 눈에 잘 안들어왔다. 그래서 다시 정리하려고 한다.

Android의 Context란?

아래의 그림을 통해서 Application, Service, Activity 모두 Context를 상속했다는 사실을 알 수 있다.

다음은 공식문서에 나와있는 Context의 개요입니다.

“애플리케이션 환경에 대한 전역정보가 Context로 연결된다. Context는 구현이 Android 시스템에 의해 제공되는 추상 클래스이다. 애플리케이션 별로 리소스 및 클래스에 대한 접근은 물론 Activity의 실행, 브로드캐스팅 및 Intent 수신과 같은 애플리케이션 레벨에 대한 호출을 허용한다.”

쉽게 말해 Context를 이용하면 시스템 레벨의 정보를 얻을 수 있는 메소드를 쓸 수 있으며, 시스템에 대한 리소스 확인, 데이터베이스 및 환경 설정에 대한 액세스 확보 등과 같은 서비스를 이용할 수 있다. Activity 객체도 Context 객체를 상속받으므로 Activity는 애플리케이션의 특정 자원 클래스, 애플리케이션의 환경 정보에 대해 접근할 수 있게 된다.

Context는 Android 개발에 있어 거의 모든 곳에서 사용되며, 가장 중요한 부분이므로 올바로 사용하려면 반드시 꼭 이해하고 넘어가야 한다고 생각한다. 왜냐하면 잘못 사용하게 된다면 메모리 누수로 이어질 수 있기 때문이다. 이번에는 어떤 유형의 Context가 존재하는지 확인해보도록 하자.

Application Context vs Activity Context

[Application Context]

  • 싱글톤 인스턴스이며, Activity에서 getApplicationContext()를 통해 접근할 수 있다.
  • 애플리케이션의 Lifecycle과 연결되어 있다.
  • 주로, 현재의 Context와 분리된 Lifecycle을 가진 Context가 필요할 때나 Activity의 범위를 넘어서 Context를 전달할 때 사용한다.
  • ex) 애플리케이션에서 싱글톤 객체를 생성했는데, 이 객체가 Context가 필요하다면 Application Context를 사용하면 된다.
  • 위와 같은 상황에서 Activity Context를 전달한다면 메모리 누수가 발생할 것이다. Activity Context는 Activity가 종료되면 소멸되는데, 싱글톤 인스턴스는 애플리케이션이 종료될때까지 함께하므로 종료된 Activity를 참조하게 되므로 메모리 누수가 발생한다.
  • 그 어떤 Context보다 오래 유지되는 Context가 필요할 때는 **getApplicationContext()**를 사용하는 게 좋다.

[Activity Context]

  • Activity에서 사용 가능하며 Activity의 Lifecycle과 연결되어 있다.
  • Activity 범위 내에서 Context를 전달하거나, Lifecycle이 현재 Context에 붙은 Context가 필요할 때, Activity Context를 사용한다.
  • ex) Lifecycle이 Activity에 붙은 객체를 생성해야 할 때, Activity Context를 사용할 수 있다.

[언제 어떤걸 쓰나?!]

다이얼로그를 호출하거나 Layout을 inflate 할 때, startActivity를 호출하여 Activity 실행을 제외하고는 Application Context를 사용하는 게 좋다. 이유는 메모리 누수 때문이다. 정적 객체가 Activity Context를 참조할 경우, Activity는 Lifecycle에 따라 onDestory()시 소멸된다. 하지만, 정적 객체가 Activity Conext를 참조하고 있기 때문에 GC의 대상에서 제외된다. 이에 따라 메모리를 회수하지 못해 OOM(Out Of Memory)의 원인이 될 수 있다.

따라서 위에서 언급한 3가지 경우를 제외하고는 applicationContext를 사용하는 편이 좋다,

Ref