Android

[Android] ViewModel의 인스턴스 공유 문제 + hiltNavGraphViewModels

도우 2024. 7. 8. 17:02
반응형

문제 원인

MVVM 디자인 패턴을 따라서 앱 제작을 하던 중 두 Fragment간 ViewModel의 인스턴스 공유 문제가 발생했다.

private val homeViewModel: HomeViewModel by viewModels()

나는 처음엔 Fragment의 각각에 위 코드를 작성하면 같은 ViewModel을 사용할 것이라고 생각했다. 하지만 by viewModels()를 사용하면 각 Fragment가 고유한 ViewModel 인스턴스를 생성하기 때문에 LiveData가 변경되더라도 Fragment에서 감지하지 못했다. 이는 각각의 Fragment가 서로 다른 ViewModel 인스턴스를 참조하고 있었기 때문이다.

 

해결 방법

해결 방법은 간단했다.

private val homeViewModel: HomeViewModel by activityViewModels()

ViewModel을 Fragment 범위가 아닌 Activity 범위에서 공유하도록 변경했다. 이를 위해 viewModel() 대신 by activityViewModel()을 사용했다. 이렇게 함으로써, 두 Fragment가 동일한 ViewModel 인스턴스를 참조하게 되었다. 

 

결과

Fragment 전환 과정의 오늘 날짜에서 선택한 날짜로 LiveData를 변경하는 로그

ViewModel을 사용하는 경우, Activity와 Fragment 간의 범위(scope)를 명확히 이해할 필요가 있다.

 

+ Hilt를 사용한 문제 해결 방법

Hilt와 Navigation 컴포넌트를 함께 사용하면 내가 겪었던 ViewModel 인스턴스 공유 문제를 쉽게 해결할 수 있다고 한다. 화면 간 전환에서 Navigation 컴포넌트와 함께 Hilt를 사용하여 ViewModel을 주입한다는 것이다.

Hilt를 사용하면 ViewModel의 생명 주기를 Activity나 Fragment에 자동으로 맞춰 관리할 수 있다.

Hilt gradle을 설정을 하고, ViewModel을 사용하는 Fragment에 @HiltViewModel 어노테이션을 달아주자. 그리고 아래와 같이 hiltNavGraphViewModels를 사용한다.

private val homeViewModel: HomeViewModel by hiltNavGraphViewModels(R.id.nav_graph)

 

참고 : https://velog.io/@cksgodl/AndroidKotlin-ViewModel%EC%9D%84-%ED%94%84%EB%9E%98%EA%B7%B8%EB%A8%BC%ED%8A%B8-%EC%82%AC%EC%9D%B4%EC%97%90%EC%84%9C-%EA%B3%B5%EC%9C%A0%ED%95%B4%EB%B3%B4%EC%9E%90

 

반응형