[Android 개념] ViewModel과 SIS

이창민·2022년 7월 22일
0

Android 개념

목록 보기
3/9

안드로이드는 장치 회전에 따른 액티비티 소멸 및 재생성에 문제가 생길 수 있다.
이런 경우 해결하는 방법을 알아보자

ViewModel

  • 특정 액티비티 화면과 연동되어, 해당 화면에 보여줄 데이터를 형식화하는 로직을 두기 좋음
  • 모델 데이터를 화면에 보여주는 기능 수행

화면의 회전이 발생한 경우 UI상태가 초기화되면 안된다. 이런 경우 ViewModel을 사용한다.

ViewModel 인스턴스는 액티비티 생명주기와 연동된다.
ViewModel 인스턴스는 액티비티 상태변화와 무관하게 액티비티가 종료될 때까지 메모리에 남아 있다가 액티비티가 종료되면 소멸된다.
Activity.onDestroy()가 호출된 경우 Activity.isFinishing속성으로 이 값이 false 인 경우 viewModel이 메모리에 남아있고 true인 경우 viewModel이 소멸된다.

장치 회전 등 구성 변경이 생길 때
액티비티 인스턴스는 소멸되고 새로운 인스턴스가 생성되지만
연관된 viewModel은 메모리에 남아 여전히 사용됨.

만약 viewModel이 액티비티나 다른 뷰의 참조를 가지면(강한 참조) 메모리 유실이 발생한다.
why?
장치 회전 시 액티비티 인스턴스는 소멸되지만, ViewModel 인스턴스는 메모리에 남는다. 이 때 viewModel이 액티비티 인스턴스에 대한 강한 참조를 가지면 2가지 문제가 발생한다.
1. 액티비티 인스턴스가 메모리에서 제거되지 않아 이 인스턴스가 사용하는 메모리 유실
2. ViewModel 인스턴스가 현재 사용되지 않는 과거 액티비티의 참조를 가져 ViewModel 인스턴스가 과거 액티비티의 뷰를 변경하려 하면 IllegalStateException 발생

SIS(SaveInstanceState)

안드로이드 OS가 앱의 프로세스를 소멸시킬 때는 메모리에 있는 앱의 모든 액티비티들과 ViewModel들이 제거되지만, 액티비티나 ViewModel의 어떤 생명주기 콜백 함수도 호출하지 않는다.

그렇다면, 액티비티가 소멸될 때 UI 상태 데이터를 보존해 액티비티의 재구성에 사용할 수 있는 방법은?
SIS(Saved Instance State)에 데이터를 저장하는 방법이 있다.

  • 안드로이드 OS가 일시적으로 액티비티 외부에 저장하는 데이터
  • onSaveInstanceState(Bundle)을 오버라이드해 SIS에 데이터 추가 가능
  • 액티비티가 중단상태로 바뀔 때 언제든지 안드로이드 OS가 onSaveInstanceState(Bundle) 호출

사용법

	/*
     * Activity
     */
     
    private const val KEY_INDEX = "index"
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d(TAG, "onCreate(Bundle?) called")
        setContentView(R.layout.activity_main)
        
        val currentIndex = savedInstanceState?.getInt(KEY_INDEX, 0) ?: 0
        quizViewModel.currentIndex = currentIndex
    }
     
    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        Log.d(TAG, "onSaveInstanceState")
        outState.putInt(KEY_INDEX, quizViewModel.currentIndex)
    }

onSaveInstanceState를 오버라이드해 저장할 값을 저장한다.
onCreate에서 Bundle 객체에서 저장한 값을 얻어와 사용한다.

ViewModel vs SIS

ViewModelSIS 모두 장치 회전이 발생한 경우 즉..
액티비티의 인스턴스가 소멸된 경우 데이터를 유지해 UI 그대로 다시 표시할 수 있다.

무엇을 써야할까?

SIS에는 크거나 복잡한 객체를 저장하는 것은 피해야한다. -> 소량의 정보 저장
ViewModel에는 많은 데이터에 빠르고 쉽게 접근하고자 메모리에 캐싱할 때 사용

그렇다면 장기간 저장해야하는 데이터의 경우 무엇을 사용해야할까?
이는 ViewModelSIS가 아닌 DBShared preference에 저장해야한다.

profile
android 를 공부해보아요

0개의 댓글