ABOUT ME

-

  • Android) SavedStateHandle 알아보기
    Android 2020. 12. 22. 18:57

     

    안드로이드에서 ViewModel을 사용하면, 화면 회전 같은 Configuration 변경의 경우 상태를 보존 할 수 있습니다.

    그럼 ViewModel을 사용하면 액티비티 상태 유지가 가능한거 아닌가요?

     

    네. 아래의 경우에는 ViewModel 만으로 상태 유지를 할 수 없습니다. 
    시스템에 의해서 Activity가 종료되는 경우 ViewModel도 함께 메모리에서 제거 되기 때문입니다.

    사용자가 명시적으로 Activity를 종료한 케이스

    • Back(뒤로가기) 버튼 누른 경우
    • 최근 앱 화면에서 앱을 밀어서 종료시킨 경우
    • 상위 액티비티로 이동한 경우
    • 설정화면에서 앱을 강제로 종료한 경우
    • finish() 메소드를 호출하여 Activity 종료한 경우

     

    아래의 표는 시스템에 의해 Activity가 종료 되었을 경우 상태를 유지할 수 있는 경우를 보여주고 있습니다.

     

    ViewModel의 이러한 한계를 극복하기 위해서 SavedState 모듈이 추가되었습니다.

    SavedStateHandle

    • SavedStateHandle 정보가 ViewModel로 전달되어야 합니다.
    • SavedStateViewModelFactory를 사용해야만 ViewModel을 통해서 SvaedStateHandled을 전달 가능합니다.
    • SvaedStateHandled은 Key-Value로 이루어진 Map 형태입니다.
    • 시스템이 프로세스를 종료하더라도 동일한 정보를 유지할 수 있습니다.
    • get(String) ➡ 값 읽기
    • getLiveData(String) ➡ MutableLiveData가 반환, LiveData를 통해 값을 사용 가능합니다.
    • set(String, Object) ➡ 값 쓰기
    • contains(String) ➡ 값 포함
    • removes(String) ➡ 값 삭제
    • SavedStateHandle에 저장되는 데이터는 가볍고 단순해야 합니다. -> 복잡한 데이터나 큰 데이터는 데이터베이스 사용.

     

    Usage

     

    아래의 예제는 Activity의 count를 올려 시스템 종료시에 상태 유지를 위한 예제입니다.

     

    • SavedStateHandle을 ViewModel에서 사용하기 위해 생성자를 ViewModel에 포함시킵니다.
    • SavedStateHandle을 받도록 ViewModel 인스턴스를 생성하기 위해 Factory 클래스를 만들어야 합니다.
    • SavedStateHandle의 set, get 메소드를 이용하여 count 변수의 상태를 유지할 수 있습니다.
    import androidx.lifecycle.SavedStateHandle
    import androidx.lifecycle.ViewModel
    
    class SavedViewModel(private val savedStateHandle: SavedStateHandle) : ViewModel() {
    
        var count = 0
            set(value) {
                savedStateHandle.set("count", value)
                field = value
            }
    
        init {
            savedStateHandle.get<Int>("count")?.run {
                count = this
            }
        }
    }

     

    import android.os.Bundle
    import androidx.appcompat.app.AppCompatActivity
    import androidx.lifecycle.SavedStateViewModelFactory
    import androidx.lifecycle.ViewModelProvider
    
    class SavedActivity : AppCompatActivity() {
    
        private lateinit var viewModel: SavedViewModel
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            viewModel = ViewModelProvider(
                this, SavedStateViewModelFactory(
                    application,
                    this
                )
            ).get(SavedViewModel::class.java)
        }
    }

     


    References

    SavedStateHandle과 함께 ViewModel의 상태를 저장하자

    SavedStateHandle을 다뤄봅니다

    반응형

    댓글

Designed by Me.