코딩/코드리뷰

savedStateHandle로 ViewModel의 상태를 저장하자

코딩하는후운 2023. 5. 18. 09:19
반응형

savedStateHandle로 ViewModel의 상태를 저장

PR리뷰로 (Activity or Fragment)에서 사용하던 savedInstanceState를 ViewModel의 savedStateHandle로 사용해달라는 요청이 왔습니다.

검색하면서 궁금했던 점

1. 아래 글을 보면 savedStateHandle.set과 get이 있습니다.

따로 set/get은 하지 않아도 된다고 함.
savedStateHandle 안에 intent로 넘어온 값이 들어있음

로그를 직접 찍어보니
Fragment의 savedInstanceState는 null이고 (true값)
ViewModel의 savedStateHandle는 데이터가 있었다.  (intent안에 있는 값들이다.)

그래서 뷰 모델의 LifeCycle은 Activity보다 크기 때문에
뷰 모델이 Destroy되면 화면이 아예 종료된것으로 판단하여, 

override fun onSaveInstanceState(outState: Bundle) 부분에서 따로 데이터를 저장해 줄 필요가 없다. (뷰모델은 유지 되기 때문)

하지만, 화면도 종료되고 뷰모델도 종료가 되었는데 데이터를 추후에 불러와야 한다면 따로 저장 처리를 해야함.
예) 알림장 작성중 -> 화면 종료 -> 다시 알림장 작성화면 (작성하던 내용 입력 되도록 하는 예제)

2. 검색 내용에 ViewModel을 SavedStateViewModelFactory로 생성해야 한다고 되어있다.

요새에는 by로 위임하여 생성하기 때문에 내부적으로 알아서 생성 해주는 것 같다.

 

savedStateHandle 검색 내용

ViewModel을 위한 saved state 모듈은 lifecycle 버전 2.2.0에서 추가 되었다.

savedStateHandle을 ViewModel에서 다루기 위해서는
savedStateHandle을 받는 생성자를 ViewModel에 포함해야 한다.

class MainViewModel(val savedStateHandle: SavedStateHandle) : ViewModel() {
    ...
}

SavedStateHandle을 받도록 ViewModel 인스턴스를 생성하려면
AbstractSavedStateViewModelFactory를 확장하는 Factory 클래스를 만들어야 한다.

class MainActivity : AppCompatActivity() {
    private lateinit var viewModel: MainViewModel
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        viewModel = ViewModelProvider(this, SavedStateViewModelFactory(application, this)).get(MainViewModel::class.java)
    }
}

ViewModel의 SavedStateHandle을 이용하여 간단한 데이터를 저장하고 복원하는 코드를 구현할 수 있다.
사용법) 정수형 count 변수의 상태를 저장하고 복원하는 코드다.

class MainViewModel(private val savedStateHandle: SavedStateHandle) : ViewModel() {
    var count = 0
    set(value) {
        savedStateHandle.set("count",value)
        field = value
    }
    init {
        savedStateHandle.get<Int>("count")?.run {
            count = this
        }
    }
}

 

테스트 방법
시스템에 의한 Activity소멸 케이스를 테스트 하고 싶다면, 
개발자 모드 > 액티비티 유지안함 옵션을 활성화 하자.
백그라운드로 진입하는 순간 바로 Activity가 소멸되고, 포어그라운드로 재진입했을 때 새로운 Activity가 생성되는 것을 확인할 수 있다. 또한 개발자 모드에서 백그라운드 프로세스 개수에 제한을 거는 방법도 유효하다.

 

참조 :

https://charlezz.medium.com/ui-%EC%83%81%ED%83%9C-%EC%A0%80%EC%9E%A5-%EB%B0%8F-%EB%B3%B5%EC%9B%90%EC%9D%98-%ED%95%84%EC%9A%94%EC%84%B1-a00297e7a20b

반응형

'코딩 > 코드리뷰' 카테고리의 다른 글

자바 함수 및 exception 발생 여부  (0) 2023.04.11
Observable, Single 비교  (0) 2022.01.27
Observable subscribeOn, observeOn 스레드  (0) 2022.01.27
TakeIf로 값 넣기  (0) 2021.12.20
변수 3개 선언하기  (0) 2021.11.23