[Android] Context, 너 대체 뭐야?

H43RO·2021년 9월 16일
10

Android 와 친해지기

목록 보기
9/26
post-thumbnail

💡 아래 아티클을 참고하여 작성한 내용입니다
https://blog.mindorks.com/understanding-context-in-android-application-330913e32514

안드로이드 앱 개발을 해본 사람들이라면, 다양한 동작에 사용되는 Context 라는 키워드 자체를 많이 봐왔을 것이다. 하지만, 정확히 이것이 어떤 역할을 하는 지 모르는 경우가 많다. 또한, 필자조차 'Context 가 뭐예요?' 하고 질문이 들어온다면, 포인트만 집어 정확하게 대답하지 못할 것 같다.

따라서 이번 포스팅에선, Android 에서 Context 의 개념에 대해 확실히 알아보려고 한다.

Context 의 사전적 정의

맥락, 전후 사정 등을 의미한다. 안드로이드에서의 Context 도 얼추 비슷한 뉘앙스이다. 어플리케이션에 대해서 현재 상태를 나타내는 역할을 하는데, 앱이 흘러가는 맥락 정도로 해석하면 어느 정도 이해가 될 것이다. 그럼 이제 개념을 살펴보자.


Android Context 4줄 요약

  • 어플리케이션의 현재 상태를 갖고 있음

  • 시스템이 관리하고 있는 액티비티, 어플리케이션의 정보를 얻기 위해 사용

  • 안드로이드 시스템 서비스에서 제공하는 API (리소스, DB, Shared Preferences 등) 에 접근하기 위해 사용
    getResource() 같은 메소드를 써봤다면 이해하기 쉽다. 이 얘기 하는 거다.

  • Activity, Application 클래스는 Context 클래스를 상속받은 클래스

Context 는 안드로이드 앱 개발에 있어 필수적인 사항이고, 매우 중요하기 때문에 이를 정확히 이해하고 올바르게 사용하는 것이 중요하다. Context 의 잘못된 사용은, 메모리 릭 문제로 이어질 수 있기 때문에 정말 주의해야 한다.

이러한 Context 는, 크게 나누자면 또 두 가지로 나눌 수 있다.

  1. Application Context

  2. Activity Context

이렇게 두 종류의 Context 가 존재하기 때문에, 안드로이드 개발자들은 가끔 어디에 어떤 Context 를 사용해야 할지 헷갈리는 경우가 있을 것이다. 그럼, 이것들이 뭐고 어떤 용도로 사용되는지에 대해 알아보자. 하나씩 이들 각각에 대해 살펴보자.


Application 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 를 넘겨주면 된다.


Activity 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 를 사용하면 안되는 경우

  • 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 를 활용한 객체를 메모리에서 할당 해제하지 않고 있을 경우, 메모리 릭을 발생할 가능성이 농후하다.


KeyPoint

항상 가장 가까운, 밀접한 스코프의 Context 를 골라 사용하면 된다. 액티비티에서 사용된다면 Activity Context 를, 어플리케이션 전역에서 (싱글톤 등) 사용된다면 Application Context 를 사용하면 된다. 이렇게만 사용하면 메모리 릭 걱정은 없다.


오늘은 안드로이드 개발 시 자주 등장하는 Context 의 개념과 올바른 용법에 대하여 알아보았다. 평소에 헷갈렸던 부분이었다면 이 글에서 끝나는 것이 아닌, 관련 자료를 더 탐색해가며 개념을 탄탄히 하길 바란다.

profile
어려울수록 기본에 미치고 열광하라

3개의 댓글

comment-user-thumbnail
2022년 4월 7일

와우 이게 정말 도움되네요

답글 달기
comment-user-thumbnail
2023년 1월 19일

예시를 많이 들어주셔서 이해에 도움이 많이 되었습니다. 감사해요 :D

답글 달기
comment-user-thumbnail
2024년 4월 27일

쉽고 깊은 설명 감사합니다 ^^

답글 달기