안드로이드의 Context를 이해하고, 메모리 누수를 방지하기

Charlezz
5 min readNov 3, 2020

--

안드로이드의 Context란 무엇일까?

Context란 사실 단어 그대로 맥락(Context)을 의미하며, 현재의 상태를 나타낸다. 다음 내용을 읽어보면 좀 더 Context를 이해하는데 도움 될 것 같다.

Context에 대한 중요한 몇 가지 사실들!

  • Application의 현재 상태를 Context를 통해 표현한다.
  • Activity 그리고 Application의 정보를 Context를 통해 얻을 수 있다.
  • Context를 활용하여 Resource, Database, SharedPrefernces 등의 시스템 자원을 얻을 수 있다.
  • Application과 Activity 클래스 둘다 Context를 확장한 서브클래스다.

Context는 안드로이드 앱 개발을 할 때 모든 곳에서 쉽게 접할 수 있다. 안드로이드 앱 개발에 가장 중요한 요소이기 때문에 이를 잘 이해하고 사용하는 것이 중요하다.

Context를 잘못 사용하면 메모리 누수를 발생시킬 수 있다.
Context의 서브클래스인 Activity를 예로 들어 메모리 누수가 발생하는 경우를 살펴보자.

  • ViewModel 등에서 Activity를 멤버 변수로 참조하는 경우.
  • non-static inner class로 선언된 Handler를 Activity에서 사용하는 경우.
  • (Text)View를 static 변수로 선언하고 Activity가 이를 참조하는 경우
  • Singleton에서 Activity를 참조하는 경우

안드로이드에서는 다양한 타입으로 Context가 존재하기 때문에, 언제-어디서-어떻게 이 Context를 사용해야하고, 참조되고 있는지 헷갈릴 수 있다. 일단 이 두가지만 기억해보자

안드로이드에서 주로 사용하는 Context 2가지

  • Application Context: 이 Context는 안드로이드 애플리케이션 그 자체이며, 현재 애플리케이션 상태를 표현한다. 예를 들면, Application을 확장한 MyApplication 클래스가 존재 한다고 가정하면, Application Context는 MyApplication의 전용 인스턴스다.
  • Activity Context: 이 Context는 마찬가지로 Activity이자 Activity를 표현한다. MainActivity라는 클래스가 있다면 Activity Context는 MainActivity 전용 인스턴스다.

Application Context

Application Context는 Activity에서 getApplicationContext() 메서드를 통해 접근할 수 있는 인스턴스다. 이 Context는 애플리케이션의 생명주기와 묶여있다. Application Context는 생명주기가 현재 Context와 분리된 Context가 필요하거나 Activity 범위보다 큰 Context를 전달 할 때 사용된다.

Application의 범위는 Activity보다 크기 때문에 만약 Application내에서 Activity를 참조하게 되면 메모리 누수가 발생한다. 앱개발에 사용되는 많은 라이브러리들이 초기화에 Context가 필요한데 이때 Activity가 아닌 Application을 일반적으로 요구하는 이유가 바로 이점이다.

Activity Context

Activity Context는 Activity 내에서 사용가능한 Context다. 이 Context는 Activity의 생명주기에 묶인다. Activity 범위 내에서 Context를 전달하거나 현재 Context에 생명주기가 엮여있는 Context가 필요한 경우에만 Activity Context를 사용해야 한다.

Application Context와 Activity Context간 계층은 다음 그림과 같다.

MyApplication이나 MainActivity나 다 같은 Context지만 Scope가 상이하고, Activity의 경우 Application Context를 참조할 수 있다.

어떤 Context를 언제 사용해야 할까?

Application을 확장한 MyApplication과 여러 Activity 클래스들이 있다고 가정하자. 또한 앱에서 데이터베이스를 관장하는 AppDatabase라는 클래스가 싱글톤으로 존재한다고 가정하자. AppDatabase는 아마 초기화시 Context를 필요로 할것이다. 이 때 어떤 Context를 참조해야 할까?

정답은 바로 Application Context다. 왜냐면 Activity Context를 전달 한다고 가정했을 때, Activity는 생명주기에 따라 어느시점에 분명히 소멸(Destryed)되지만, AppDatabase는 싱글톤이므로 해당 Activity Context를 지속적으로 참조하고 있게되어 메모리 누수를 일으킨다.

또한, Application Context는 Activity Context가 지원하는 모든 것을 지원하지 않기 때문에, GUI와 관련된 모든것에 대해서 Application Context는 정상적으로 동작하지 않을 수 있다. 그렇기 때문에 무조건 Application Context를 사용하는 것은 옳지 않다. 예를 들면 Dialog와 같은 객체는 Activity Context를 필요로 한다.

생명주기에 따른 범위(Scope)를 명심하고, 조심해서 Context를 참조하도록 하자.

--

--