[Android] ViewModel에서 Context를 참조하면 안되는 이유

문승연·2023년 12월 15일
0

Android-MVVM

목록 보기
3/3

1. Context가 정확히 뭐지?

안드로이드 개발을 하다보면 필연적으로 Context라는 녀석을 사용하게 된다.

Context를 안드로이드 공식 홈페이지에서는 다음과 같이 설명하고 있다.

Interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc.
출처

필자의 뛰어나지 않은 영어 실력으로 해석 및 요약해보자면... 애플리케이션에 대한 글로벌 정보를 가지고 있는 인터페이스. 여기서 글로벌 정보란 패키지명, 리소스 정보와 같은 앱 자체 데이터들을 이야기하는 거 같다. 뿐만 아니라 다른 액티비티를 실행하거나 브로드캐스팅, 인텐트 정보 받기 등 애플리케이션 단계에서의 동작을 가능하게 해주는 것 역시 이 Context이다.

Context에 대한 좀 더 자세한 이야기는 다른 포스트에서 다루도록 하고 일단은 ViewModel 이야기로 넘어가보자.

2. ViewModel에서 Context를 참조하면 안되는 이유

이를 이해하기 위해선 먼저 ViewModelActivity의 생명주기에 대해서 알아야한다.

ViewModel의 생명주기는 Activity가 최초 생성될 때 함께 시작한다.

하지만 Activity가 onDestroy 되고 다시 onCreate 되는 경우 ViewModel은 소멸되지 않고 그대로 유지되는 것을 확인할 수 있다.

가장 대표적인 예시로 화면 회전을 들 수 있다. 안드로이드 기기에서 화면을 회전할 경우 UI를 다시 그리기 위해 Activity가 onDestroy 를 호출해 종료한 다음 다시 onCreate 처음부터 생성된다.

하지만 Activity가 이런 소멸과 생성을 반복하는 동안 ViewModel은 소멸되지 않고 유지된다. ViewModel이 완전히 종료되는 것은 Activity가 완전히 종료되었을 때 (혹은 Fragment가 완전히 분리되었을 때) 뿐이다.

자 이제 여기서 ViewModelContext를 참조하고 있다고 가정해보자. 그리고 그 상태에서 화면 회전이 일어나 Activity가 소멸되고 다시 생성되었다면?

ViewModel은 이미 소멸되었던 Activity의 Context를 참조하게 될 것이고 이는 충돌이나 예외 등의 문제로 이어질 수 있다.

3. 그럼 아예 Context를 참조할 방법이 없는가?

ViewModel에서 Context를 참조하면 안된다는 것을 알겠는데 그럼에도 불구하고 부득이하게 참조해야만 하는 상황이 발생한다면?

이런 경우를 위해서 Application을 참조하고 있는 AndroidViewModel이라는 ViewModel의 확장 클래스가 존재한다.

AndroidViewModel을 상속받아 ViewModel을 구현하면 예시와 같은 방식으로 Application Context를 활용할 수 있다.

val context = getApplication<Application>().applicationContext

위의 내용을 정리한 공식 문서 내용으로 마무리 하겠다.

주의: ViewModel은 뷰, Lifecycle 또는 활동 컨텍스트 참조를 포함하는 클래스를 참조해서는 안 됩니다.
ViewModel 객체는 뷰 또는 LifecycleOwners의 특정 인스턴스화보다 오래 지속되도록 설계되었습니다. 이러한 설계로 인해 뷰 및 Lifecycle 객체에 관해 알지 못할 때도 ViewModel을 다루는 테스트를 더 쉽게 작성할 수 있습니다. ViewModel 객체에는 LiveData 객체와 같은 LifecycleObservers가 포함될 수 있습니다. 그러나 ViewModel 객체는 LiveData 객체와 같이 수명 주기를 인식하는 Observable의 변경사항을 관찰해서는 안 됩니다. 예를 들어 ViewModel은 시스템 서비스를 찾는 데 Application 컨텍스트가 필요하면 AndroidViewModel 클래스를 확장하고 생성자에 Application을 받는 생성자를 포함할 수 있습니다(Application 클래스가 Context를 확장하므로).

레퍼런스)
1. Android ViewModel에서 Context를 올바르게 사용하는 방법

profile
"비몽(Bemong)"이라는 앱을 개발 및 운영 중인 안드로이드 개발자입니다.

0개의 댓글