💡 아래 아티클을 참고하여 작성한 내용입니다
https://blog.mindorks.com/understanding-context-in-android-application-330913e32514
안드로이드 앱 개발을 해본 사람들이라면, 다양한 동작에 사용되는 Context
라는 키워드 자체를 많이 봐왔을 것이다. 하지만, 정확히 이것이 어떤 역할을 하는 지 모르는 경우가 많다. 또한, 필자조차 'Context 가 뭐예요?' 하고 질문이 들어온다면, 포인트만 집어 정확하게 대답하지 못할 것 같다.
따라서 이번 포스팅에선, Android 에서 Context
의 개념에 대해 확실히 알아보려고 한다.
맥락, 전후 사정 등을 의미한다. 안드로이드에서의 Context 도 얼추 비슷한 뉘앙스이다. 어플리케이션에 대해서 현재 상태를 나타내는 역할을 하는데, 앱이 흘러가는 맥락 정도로 해석하면 어느 정도 이해가 될 것이다. 그럼 이제 개념을 살펴보자.
어플리케이션의 현재 상태를 갖고 있음
시스템이 관리하고 있는 액티비티, 어플리케이션의 정보를 얻기 위해 사용
안드로이드 시스템 서비스에서 제공하는 API (리소스, DB, Shared Preferences 등) 에 접근하기 위해 사용
→ getResource()
같은 메소드를 써봤다면 이해하기 쉽다. 이 얘기 하는 거다.
Activity
, Application
클래스는 Context
클래스를 상속받은 클래스
Context
는 안드로이드 앱 개발에 있어 필수적인 사항이고, 매우 중요하기 때문에 이를 정확히 이해하고 올바르게 사용하는 것이 중요하다.Context
의 잘못된 사용은, 메모리 릭 문제로 이어질 수 있기 때문에 정말 주의해야 한다.
이러한 Context
는, 크게 나누자면 또 두 가지로 나눌 수 있다.
Application Context
Activity Context
이렇게 두 종류의 Context 가 존재하기 때문에, 안드로이드 개발자들은 가끔 어디에 어떤 Context 를 사용해야 할지 헷갈리는 경우가 있을 것이다. 그럼, 이것들이 뭐고 어떤 용도로 사용되는지에 대해 알아보자. 하나씩 이들 각각에 대해 살펴보자.
이 녀석은 Activity
에서 applicationContext
라는 프로퍼티를 통해 얻을 수 있는 (코틀린 기준, 자바의 경우 getApplicationContext()
라는 메소드를 통해 얻을 수 있음) 싱글톤 인스턴스이다.
이 Context 는 어플리케이션 라이프사이클과 묶여있어, 현재 Context 가 종료되고 나서도 Context 가 필요한 작업이나, 액티비티 범위를 벗어난 곳에 Context 가 필요한 작업에 적합하다.
예를 들어, 어플리케이션 내에 싱글톤 객체를 만드려고 하는데 이 객체가
Context
를 필요로 할 때, Application Context 를 사용하면 된다. 만약 이런 상황에 Activity Context 를 넘겨주게 되면, Activity 에 대한 참조를 메모리에 남겨두며 GC (Garbage Collected) 되지 않은 채 분명 메모리 릭이 발생할 것이다.
그럼, 어플리케이션 전역에서 사용할 어떤 라이브러리를 MainActivity
에서 초기화 할 때 Context 가 필요하다고 가정해보자. 어떤 Context 를 넘겨줘야 할까?
정답은 Application Context 이다. 만일 Activity Context 를 넘겨주게 되면, MainActivity
에 대한 참조가 메모리 상에서 GC 되지 않아 메모리 릭이 발생하기 때문이다.
따라서, 오랫동안 지속되거나 앱 전역에서 사용될 녀석의 경우 Application Context 를 넘겨주면 된다.
해당 Context 는 액티비티 안에서만 사용 가능하다. 특정 Activity
의 라이프 사이클에 종속되어 있다. 이 녀석은 Activity
스코프 내에서 사용될 때 넘겨주거나, Activity
와 라이프사이클이 같은 객체를 생성할 때 넘겨준다. 즉, Activity
가 소멸되면 해당 Context
도 같이 소멸되는 것이다.
아래와 같은 앱이 있다고 해보자.
그렇다면, 각각 컴포넌트의 입장에서 Context
의 사용 가능 여부를 살펴보자.
MyApplication : Application Context 사용 가능
MainActivity1 : Application Context, Activity 1 Context 사용 가능
MainActivity2 : Application Context, Activity 2 Context 사용 가능
어떤가, 이제 조금 이해가 되는가?
하는 사람들을 위해 조금 더 살펴보자. 예시 상황을 두 개 정도 보며, 각 상황에 어떤 Context 를 사용하면 적절한지에 관해 알아보도록 하자.
👮🏻♀️ Q1.
MyApplication
클래스와MyDB
싱글톤 객체가 있을 때,MyDB
가 Context 를 필요로 하는 경우, 어떤 Context 를 넘겨줘야 할까?
- 정답 : Application Context
만약 Activity Context 를 전달했다면, 액티비티가 사용되지 않을 때에도MyDB
가 해당 액티비티를 참조하고, 아까 말한대로 메모리 릭이 발생할 것이다. 따라서, 싱글톤 객체에서 Context 를 필요로 하는 경우, 무조건 Application Context 를 사용해야 한다. 필수다.
👮🏻♀️ Q2.
Toast
,Dialog
등의 UI 동작에 있어 Context 가 필요하다면, 어떤 Context 를 넘겨줘야 할까?
- 정답 : Activity Context
해당 UI 컴포넌트들은 어차피 Activity 의 라이프 사이클에 종속되는 것들이기 때문에, Activity Context 를 사용해주면 된다.
그리고, applicationContext
혹은 getApplicationContext()
를 사용해선 안되는 경우도 있다.
Application Context 는 Activity Context 가 지원하는 모든 것을 지원하지 않는다. 만능처럼 보이지만 절대 아니다. 따라서 GUI (View Component 등) 관련 동작들에 있어 Application Context 는 오류를 발생할 확률이 높다.
예를들어,
Application Context
를 활용하여AlertDialog
를 show() 하게 되면java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
과 같은 오류를 맛볼 수 있다. 따라서 조심하여 사용하도록 하자.
Activity 는 Garbage Collection 이 가능하지만, Application 은 앱 프로세스가 살아있는 동안 계속하여 남아있다. 따라서, Application Context 를 활용한 객체를 메모리에서 할당 해제하지 않고 있을 경우, 메모리 릭을 발생할 가능성이 농후하다.
항상 가장 가까운, 밀접한 스코프의 Context 를 골라 사용하면 된다. 액티비티에서 사용된다면 Activity Context 를, 어플리케이션 전역에서 (싱글톤 등) 사용된다면 Application Context 를 사용하면 된다. 이렇게만 사용하면 메모리 릭 걱정은 없다.
오늘은 안드로이드 개발 시 자주 등장하는 Context
의 개념과 올바른 용법에 대하여 알아보았다. 평소에 헷갈렸던 부분이었다면 이 글에서 끝나는 것이 아닌, 관련 자료를 더 탐색해가며 개념을 탄탄히 하길 바란다.
와우 이게 정말 도움되네요