안드로이드 프로그래밍을 하며 제일 흔하게 인자로 사용되는 타입이 Context인 것 같습니다. Context를 잘못 사용하면 앱이 비정상 종료되거나 메모리 누수가 발생하기도 하죠. 그렇다면 Context는 정확히 어떤 것을 가리키는 말일까요? 오늘은 Android의 핵심, Context에 대해 알아보겠습니다.
developer.android.com/reference/android/content/Context
Android 개발자 사이트
Context는 애플리케이션 환경에 대한 글로벌 정보를 갖는 인터페이스입니다. Context는 Android 시스템에서 구현체를 제공하는 추상 클래스로, 애플리케이션 별 리소스 및 클래스 접근에 사용되며, 액티비티 실행, 브로드캐스트, 인탠트 수신 등과 같은 애플리케이션 수준 작업에 사용됩니다.
이것만으로 컨택스트를 설명하기는 조금 부족해보입니다.
blog.mindorks.com/understanding-context-in-android-application-330913e32514
Understanding Context In Android Application
위 글의 저자 Amit Shekhar는 컨택스트에 대해 다음과 같이 설명하고 있습니다.
- 애플리케이션의 현재 상태를 나타낸다.
- 액티비티와 어플리케이션의 정보를 얻기 위해 사용할 수 있다.
- 리소스, 데이터베이스, shared preference 등에 접근하기 위해 사용할 수 있다.
- 액티비티와 애플리케이션 클래스는 Context 클래스를 확장한 클래스이다.
컨택스트는 다시 크게 두 종류로 나뉩니다:
- Application Context
- Activity Context
Application Context
애플리케이션 컨택스트는 싱글턴 인스턴스이며, 액티비티에서 getApplicationContext()를 통해 접근할 수 있습니다. 이 컨택스트는 애플리케이션 라이프사이클에 묶여있으며, 현재 컨택스트가 종료된 이후에도 컨택스트가 필요한 작업이나 액티비티 스코프를 벗어난 컨택스트가 필요한 작업에 적합합니다.
예를 들어, 애플리케이션에 싱글턴 오브젝트를 생성하고, 해당 오브젝트가 컨택스트가 필요하다면 항상 애플리케이션 컨텍스트를 전달하세요. 만약 액티비티 컨택스트를 전달한다면, 해당 오브젝트가 액티비티를 항상 참조하므로, 액티비티가 화면에 표시되지 않는 순간에도 가비지 콜렉션이 진행되지 않아 메모리 누수가 발생합니다.
애플리케이션 전체에서 사용할 라이브러리를 특정 액티비티에서 초기화한다면 어떤 Context를 전달해야 할까요? 당연히 Application Context입니다. getApplicationContext()는 딱 위와 같은 경우에만 사용하여야 합니다.
Activity Context
Activity Context는 activity 내에서 유효한 컨택스트입니다. 이 컨택스트는 액티비티 라이프사이클과 연결되어 있습니다. 액티비티 컨택스트는 액티비티와 함께 소멸해야 하는 경우에 사용합니다. 예를 들어, 액티비티와 라이프사이클이 같은 오브젝트를 생성해야 할 때 액티비티 컨택스트를 사용할 수 있습니다. 앱의 계층 구조는 다음 그림과 같습니다:
- Application Context는 MyApplication, MainActivity1, MainActivity2 모두에서 사용할 수 있습니다.
- MainActivity1의 Context는 MainActivity1에서만 사용할 수 있습니다.
- MainActivity2의 Context는 MainActivity2에서만 사용할 수 있습니다.
ContentProvider의 getContext()
추상 클래스 ContentProvider를 상속한 클래스에서 getContext() 메소드를 통해 불러올 수 있는 컨택스트는 애플리케이션 컨택스트입니다.
언제, 어떤 Context를 사용해야 할까?
상황을 가정하여 언제, 어떤 Context를 사용할 지 알아봅시다. class MyApplication과 class MyDB 싱글턴이 있다고 가정해봅시다. 그리고 MyDB가 context가 필요한 상황이라면, 어떤 context가 필요할까요?
답은 Application Context입니다. 만약 우리가 Activity의 Context를 전달했다면, 액티비티가 사용되지 않는 경우에도 MyDB가 불필요하게 액티비티를 참조하고, 메모리 누수가 발생할 것입니다. 그러므로 싱글턴의 경우에는 항상 애플리케이션 컨택스트를 전달하는 게 맞습니다.
그렇다면 언제 액티비티 컨택스트를 사용해야 할까요? 언제든 액티비티를 사용할 때, Toast, Dialog 등의 UI operation에서 컨택스트가 필요하다면 이때 액티비티 컨택스트를 사용해야 합니다.
항상 가능한 한 가까운 컨택스트를 사용하도록 합시다. 액티비티에 있다면, 액티비티 컨택스트를, 애플리케이션에 있다면, 애플리케이션 컨택스트를 사용합니다. 싱글턴의 경우에는 애플리케이션 컨택스트를 사용합니다.
getApplicationContext()를 쓰면 안 되는 경우
- Application Context는 Activity Context가 제공하는 기능 전체를 제공하진 않습니다. 특히 GUI와 관련된 컨택스트 조작은 실패할 확률이 높습니다.
- Application Context가 사용자 호출로 생성된, clean up 되지 않은 객체를 가지고 있다면 메모리 누수가 발생할 수 있습니다. Activity 객체는 가비지 콜렉션이 가능하지만 Application 오브젝트는 프로세스가 살아있는 동안 남아있습니다.
Rule of Thumb
대부분의 경우 가장 가까운, 스코프에 해당하는 컨택스트를 직접 사용하세요. 참조가 해당 컴포넌트의 라이프사이클을 넘어서지 않는 이상 메모리 누수 걱정 없이 컴포넌트를 유지할 수 있습니다. 액티비티나 서비스 이외의 객체에서 컨택스트를 참조해야 하는 경우 액티비티 컨택스트가 아닌, 애플리케이션 컨텍스트로 전환하세요.
'Android' 카테고리의 다른 글
#Broadcast Receiver 비동기 백그라운드 작업 #doAsync #JobScheduler (0) | 2021.02.18 |
---|---|
#BroadcastReceiver 부팅 시 실행, android.intent.action.BOOT_COMPLETED 받기 (0) | 2021.02.15 |
View Binding = findViewById 대체하는 방법, View Binding과 Data Binding 차이 (1) | 2021.02.08 |
#Volley 로 안드로이드 앱에 #API #JSON 연결하기 (0) | 2021.02.02 |
안드로이드 데이터 바인딩 in Java (0) | 2021.01.13 |