안드로이드 개발을 시작하고 꽤 많은 코드에서 Context를 명시하라는 조건이 있었다.
Context가 사전적 의미로 대충 문맥, 맥락 이런 뜻이기에 그냥 현재 Activity를 의미하는 줄 알았다.
하지만 자세히 파보니 Context가 단순 현재 Activity만을 의미하는 것이 아닌 것을 알게 되었고,
계속 공부를 할수록 Context를 명시해야 하는 코드가 많아지기에(ViewModel Observable 등등..),
개념을 정확히 이해할 필요성이 있어서 정리하려고 합니다.!
💡안드로이드에서의 Context
Context란 단어 그대로 맥락을 의미하며, 현재의 상태를 나타낸다고 이해하면 편할 거 같습니다
Context에 대한 중요한 몇 가지 사실 들
- 애플리케이션의 현재 상태를 Context를 통해 표현한다.
- 액티비티 그리고 애플리케이션의 정보를 Context를 통해 얻을 수 있다.
- Context를 활용하여 리소스, 데이터베이스, SharedPrefernces 등에 접근하기 위해 사용할 수 있다.
- 액티비티와 애플리케이션 클래스는 Context 클래스를 확장한 서브 클래스이다.
Context를 알아야하는 중요한 이유는 Context를 잘못 사용하면 메모리 누수
를 발생시킬 수 있습니다.
다음과 같은 경우에 메모리 누수가 발생합니다.
- ViewModel 등에서 Activity를 멤버 변수로 참조하는 경우.
- non - static inner class로 선언된 Handler를 Activity에 사용하는 경우
- (Text) View를 static 변수로 선언하고 Activity가 이를 참조하는 경우
- Singleton에서 Activity를 참조하는 경우
안드로이드에서 사용하는 Context는 2가지가 있습니다.
Activity Context Vs Application Context
이 두 종류의 context가 존재하기에, 어떤 상황에서 어떤 context가 사용해야 할지 헷갈리는 경우를 많이 겪었었다.
이제 두가지의 차이점
을 알아보고, 어떠한 용도, 상황에서 사용되는지 알기 전에 각각에 대해서 설명해 드리겠습니다.
Activity Context
해당 Context는 액비티티 안에서만 사용가능하다. 특정 Activity의 라이프 사이클에 종속되어 있다. 이 녀석은 Activity 스코프 내에서 사용될 때 넘겨주거나 , Activity와 라이프사이클 같은 객체를 생성할 때 넘겨준다.
즉, Activity가 소멸되면( onDestory() ) 해당 Context도 같이 소멸되는 것이다.
Application Context
쉽게 말하면 안드로이드 애플리케이션 그 자체이고, 현재 애플리케이션 상태를 표현한다.
자세하게 설명하자면,
Application Context는 Activity에서 getApplicationContext() 메서드를 통해 접근할 수 있는 인스턴스입니다.
이 Context는 애플리케이션 라이프사이클과 묶여있어, 현재 Context가 종료되고 나서도 Context가 필요한 작업이나,
액비비티 범위를 벗어난 곳에 Context가 필요한 작업에 적합하다.
각각 컴포넌트의 입장에서 Context의 사용 가능 여부를 살펴보자
MyApp : Application Context 사용 가능
MainActivity : Application Context, Activity Context1 사용 가능
SubActivity : Application Context, Activity Context2 사용 가능
이렇게 봐도 아직 어떤 Context가 어떤 상황에서 사용되는지 굉장히 헷갈리는 경우가 많다.
예를 들어 어플리케이션 내에 싱글톤 객체를 만드려고 하는데 이 객체가 Context를 필요로 할 때,
어떤 Context를 넘겨줘야 할까??
정답은 Application Context이다.
만약 Applicaiton Context 말고 Activity Context를 전달했다면,
액티비티가 사용되지 않을 때에도 싱글톤객체가 해당 액티비티를 계속 참조하고,
이렇게 되면 메모리 누수가 발생할 것이다.
따라서 싱글톤 객체에서 Context를 필요로 하는 경우, 메모리 누수를 방지하기 위해 Application Context를 사용해야 한다.
Toast, Dialog 등의 코드를 작성할 때에도 Context를 넘겨줘야 했습니다.
이러한 UI 동작
의 경우 어떠한 Context를 넘겨줘야 할까요?
정답은 Activity Context입니다.
해당 UI 컴포넌트들은 어차피 Activity의 라이프 사이클에 종속되는 것들이기 때문에, Activity Context를 사용해 주면 됩니다.
위에서 Activity Context를 잘못사용하면 메모리 누수가 발생한다고 했습니다.
그렇게 되면 그냥 무조건 Applicaton Context를 넘겨주면 되는 건 아니야??라는 생각을 하실 수도 있지만
잘못된 생각입니다.
❌Application Context를 사용하면 안 되는 경우
- Application Context는 Activity Context가 지원하는 모든 것을 지원하지 않습니다.
만능처럼 보이지만, GUI(View Component 등) 관련 동작들에 있어 Application Context는 오류를 발생할 확률이 높습니다. - Activity는 Garbage Collection이 가능하지만 , Application은 앱 프로세스가 살아있는 동안 계속하여 남아있다.
따라서 Application Context를 활용한 객체를 메모리에서 할당 해제하지 않고 있을 경우, 메모리 누수가 발생할 가능성이 높다.
즉 중요한 점은 항상 가장 가깝고
, 밀접한
스코프의 Context를 골라 사용하면 됩니다.
Activity 범위 안에서 동작이 끝나는 작업은 Activity Context.
현재 Context의 생명주기 넘어서는 범위에서 Context가 필요한 경우(ViewModel),
싱글톤 객체에 Context를 넘겨주는 경우. -> Application Context
이렇게만 사용한다면 메모리 누수에 걱정은 없겠죠????
정리
- 안드로이드에서 Context는 2가지 종류가 있다.
- Application Context
- Activity Context
- 각각의 쓰임의 용도를 알아야 메모리 누수를 방지할 수 있다.
- Context를 잘못사용하면 메모리 릭이 발생할 수 있다.
- 예를 들어 ViewModel에 Context를 Application이 아닌 Activity를 넘겨주게 된다면 메모리 누수가 발생한다.
왜냐하면 ViewModel이 Acitivity보다 수명주기가 길기 때문이다.- 따라서 우리는 적절한 Context를 넘겨줘야 합니다.
- 예를 들어 ViewModel에 Context를 Application이 아닌 Activity를 넘겨주게 된다면 메모리 누수가 발생한다.
- 중요한 점은 항상 가장 가까운 스코프의 Context를 골라 사용하자!!
Context를 단순히 맥락으로 이해하고 있었는데, 이렇게 중요하고 깊은 내용인 줄 몰랐습니다.
메모리 릭을 피하기 위해서는 Context의 개념을 탄탄하게 잡을 필요가 있네요
이제는 Context가 단순한 맥락이 아닌 2가지의 의미가 있다는 것을 알고 계시겠죠??
'Skils > Android' 카테고리의 다른 글
[Android] - DataBinding (0) | 2023.10.14 |
---|---|
[Android] - Navigation Component (0) | 2023.09.03 |
[Android] - Live Data (0) | 2023.02.12 |
[Android] - ViewModel (0) | 2023.02.09 |
[Android] - 안드로이드 설계 패턴(MVP) (0) | 2023.02.05 |