조각들

개요

앱잼이 끝나고 이제 리팩토링을 해야 하는 단계인데 내가 혹시 모르는 부분이 있는지, 애매하게 알고 있어서 찝찝했던 부분들을 공부하고 있다.

 

여기에 쓰이는 글은 fact라기보단, 현재까지 내가 이해하고 있는대로 쓰는 것이므로 부정확할 수 있다.

 


MVVM ViewModel, AAC ViewModel

ViewModel이 다르다는 얘기는 들어본 적이 있는데 당시에는 별 생각 없이 넘겼었다.그러다 이번에 찝찝함을 참지 못하고 결국 구글링을 해보았다. 아래 포스팅을 보고 이해를 했는데 부정확할 수 있다.

 

 

안드로이드: How to MVVM

MVVM이 뭘까요~~

medium.com

 

위 포스팅에 따르면 MVVM에서 말하는 ViewModel은 우리가 보통 ViewModel이라 했을 때 떠올리는 것과 다르다는 것이다.

 

ViewModel 클래스를 상속받아서 만드는 건 AAC ViewModel이고 MVVM에서 말하는 ViewModel은 실체가 없는 추상적인 개념이었던 것이다. 그런데 AAC ViewModel로도 MVVM 패턴을 구현해낼 수 있어서 보통 같이 쓰였던 것이지 개념적으로는 두 가지가 다르다고 한다.

 

AAC ViewModel은 Activity나 Fragment와 별개의 생명주기를 갖는 클래스이며 UI 관련 data를 저장 및 관리한다. 가령 휴대폰을 가로 모드로 돌렸을 때 View가 죽었다가 새로 생성된다. 이때 기존의 화면에 반영돼있던 UI data는 다 날아간다. 하지만 AAC ViewModel을 활용하면 별개의 생명주기를 갖고 있기 때문에 View가 죽어도 data가 날아가지 않는다.

 

여기까지가 AAC ViewModel에 대한 간략한 개념이다.

 

반면 MVVM에서 말하는 ViewModel이란 'View와 logic을 분리'하는데 활용되는 어떤 것이다. 이 어떤 것의 이름을 ViewModel이라고 할 뿐 ViewModel이라는 이름을 갖는 라이브러리가 있다거나 하는 건 아니다.

 

기존에는 Activity나 Fragment에서 logic을 작성해주었는데 이것을 따로 빼서 관리한다는 것이다. data binding을 활용하면 View에서 직접 코드를 안 써줘도 xml 상에서 다 처리가 가능하다.

 

위 포스팅에서는 양방향 data binding을 활용하여 xml에서 ViewModel에 만들어놓은 변수 value들을 update하고 

또 그렇게 update된 value들은 다시 xml로 전달되어 화면이 갱신되는 예시를 들어놨다. 그런데 이것 역시도 View의 생명주기를 따르기 때문에 화면이 가로 모드로 돌아가면 UI data가 날아간다.

그래서 AAC ViewModel을 쓴다.

 

AAC ViewModel을 상속받는 클래스를 만들고 이 안에다 View와 logic을 분리하는 코드를 작성하기만 하면 MVVM이 안 될 게 없다. 이렇게 만든 ViewModel은 화면이 돌아가도 UI data가 날아가지 않는다.

 

AAC ViewModel을 쓸 때 주의할 점은 ViewModel에 어떠한 context도 넘기면 안 된다는 것이다. 그 이유는 메모리 leak이 일어나기 때문이다. 구체적으로는 Activity가 죽어도 ViewModel은 살아있는데 이미 죽은 Activity에 대한 참조를 계속 가지고 있다는 얘기이다.

 

ViewModel에 LiveData를 써주는 건 ViewModel이 UI 관련 데이터를 로드하고 관리하는 역할을 하므로 LiveData 객체를 보유하는 데 적합하기 때문이다.

 


Data Biding, LiveData

Data Binding과 LiveData를 함께 쓸 때 주의할 점이 있다. 그것은 LifecycleOwner를 등록해줘야 한다는 것이다.

 

data binding을 안 쓴다면 가령 Activity에서 옵저버 객체에 LifecycleOwner를 등록해줄 수 있다. 이러면 LiveData는 해당 옵저버 객체의 lifecycle을 따라 옵저버가 위치한 View가 사라지게 되면 LiveData도 함께 사라진다.

 

data binding을 쓰면 별도의 옵저버 객체를 생성할 필요가 없다. 하지만 여전히 LifecycleOwner는 등록해줘야 한다.

binding.lifecycleOwner = this

 

LifecycleOwner를 등록하지 않으면 Lifecycle에 맞게 관리되지도 않고 LiveData의 상태 변화를 xml에서 감지하지 못한다.

이전에 data가 화면에 정상적으로 반영되지 않는 이슈가 있었는데 이런 이유였다.

 


Fragment 간 data 공유

이번 앱잼 때 모든 View를 Activity로 짰다가 data 공유가 번거로워서 고통을 받았었다. 그래서 View 구조를 개선하는 리팩토링을 하려고 한다. 이번 정리글에서 ViewModel을 다뤘었는데 Fragment 간 data 공유도 ViewModel을 활용하기에 같이 적어본다.

 

ViewModel 객체를 생성할 때 같은 lifecycle을 넣어주면 같은 객체를 공유한다고 한다.

 


느낀점

AAC ViewModel을 쓰기 때문에 LiveData도 쓰게 되는 거고, 이를 쓴다는 것은 옵저버를 활용한다는 것이다. ViewModel이라 명칭되는 별도의 클래스에 logic 분리를 하고 View에서 옵저버를 통해 UI 갱신을 시켜주면 "뷰와 logic의 분리 자체는 이뤄냈으니 MVVM 구현이 되는 것 아닌가?"라는 생각이 들었다. 이 고민의 요지는 data binding을 안 쓰고도 MVVM 구현이 가능하지 않냐는 것이다.

 

이전에 심화스터디에서 비슷한 질문을 한 적이 있었다. AAC ViewModel을 쓰면 LiveData와 옵저버를 통해 UI 갱신이 가능하니 data binding이 아니라 view binding을 써도 MVVM 구현이 가능하지 않냐는 내용이었는데 그때 한 스터디원이 그렇게 해도 구현은 될 텐데 MVVM 자체가 Activity에 많은 코드를 쓰기 싫다는 거니까 의도에 벗어나지 않겠냐는 답을 줬었다.

 

 

 

 

 

'Android > 공부' 카테고리의 다른 글

retrofit의 비동기 처리  (0) 2024.04.29
Flow  (2) 2024.03.14
Repository의 효용에 대한 고찰  (0) 2023.03.16
[공부] Github Action CI  (0) 2023.03.04
[공부] sopt 31기 안드로이드 세미나 과제  (0) 2022.12.05