개발새발 - IT 기술블로그
article thumbnail

안녕하세요. 앱개발을 공부하다 문득 onCreate()의 Parameter로 생성되는 savedInstanceState는 도대체 무슨 역할을 할까? 라는 의문이 들어 찾아보았습니다. 

 

 


 

 

활동 상태 변경

 

 

 

앱의 생명주기(활동 수명주기)를 참고하면, Activity는 앱의 구성이 변경되면 모든 활동이 제거되고 다시 생성됩니다.

그 과정에서 onPause(), onStop() 및 onDestory() 콜벡을 호출하고 인스턴스가 소멸되며, 새 인스턴스가 생성될 때 onCreate(), onStart() 및 onResume() 콜벡을 호출합니다.

 

savedInstanceState 는 화면 구성의 변경이 발생할 때 현재 인스턴스에서 데이터를 저장하고 새 인스턴스에서 다시 불러오기 위해 호출되며, 대표적인 구성의 변경으로는 화면모드(가로모드, 세로모드)의 전환, 입력기기(키보드) 변경, 지역 및 언어의 변경 등이 있습니다.

 

 

구성이 변경되었을 때 아래 두가지 콜벡에서 UI를 저장시키거나 저장한 UI의 데이터를 확인할 수 있습니다.

onSaveInstanceState(outState: Bundle)
onRestoreInstanceState(savedInstanceState: Bundle)

 

 

UI 상태 유지

 

 

 

시스템의 구성이 변경되었을 때 UI를 유지시키는 옵션 중 하나로 사용되며, 메모리에 저장되어 읽고 쓰여집니다.

위의 표에서 볼 수 있듯 사용자가 활동을 완전히 마쳤을 때 즉, 다시 Activity로 돌아올 이유가 없는 경우엔 savedInstanceState를 호출하지 않습니다. 아래 예제에서 확인해 보겠습니다.

 

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    Log.d(TAG,"onSaveInstanceState")
}

 

 

 

 

 

1) finish() 호출 X

btn.setOnClickListener() {
    val intent = Intent(this, IntentActivity::class.java)
    startActivity(intent)
}

 

 

2) finish() 호출 O

btn.setOnClickListener() {
    val intent = Intent(this, IntentActivity::class.java)
    startActivity(intent)
    finish()
}

 

위의 결과처럼 finish() 를 해주지 않은 상태에서 액티비티를 이동하면 onSaveInstanceState 콜벡이 호출되지만, 

finish()로 액티비티를 완전히 종료 시킨 후에 액티비티를 이동하면 onSaveInstanceState 콜벡이 호출되지 않습니다.

 

 

UI 데이터 저장

 

그럼 실제로 데이터를 저장하고 불러오는 방식에 대해 알아보겠습니다.

 

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    Log.d(TAG,"onSaveInstanceState")
    outState.putString("key","value")
}

 

Bundle 데이터 타입의 outState에 Key와 value를 String 형식으로 입력하여 저장시켰습니다.

onsaveInstanceState는 onPause() 혹은 onStop() 이후에 호출되고, 저장된 데이터는  onCreate() 와 onRestoreInstanceState()의 savedInstanceState 에서 불러 올 수 있습니다.

 

 

UI 데이터 호출

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    Log.d(TAG, "onCreate")

    if (savedInstanceState == null)
        Log.d(TAG, "액티비티가 처음 생성 됨")
    else {
        with(savedInstanceState) {
            Log.d(TAG, "액티비티가 재생성 됨 : " + getString("key"))
        }
    }
}
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
    super.onRestoreInstanceState(savedInstanceState)
    Log.d(TAG,"onRestoreInstanceState : " + savedInstanceState.getString("key"))
    val tv: TextView = findViewById(R.id.textView)
    tv.text = savedInstanceState.getString("key")
}

 

위에서 저장시킨 데이터를 불러오는 코드입니다. 액티비티가 처음 생성될 땐 onCreate의 savedInstanceStateNull 이기 때문에 액티비티의 활동상태가 초기생성상태인지 변경되어 재생성되는 상태인지를 구분해주어야합니다.

 

onRestoreInstanceState는 onStart() 이후에 호출됩니다. 위와같이 bundle에 String 형식으로 "value"가 저장되어있는 것을 확인 하실 수 있습니다.

 

 

결론

이렇게 savedInstanceState에 대해 알아보았는데요.  저장되는 데이터의 양이 가볍거나 작은 경우에 사용하시면 좋을 것 같은 기능이였습니다. 하지만 저장해야 할 데이터의 크기가 방대하거나 복잡하다면 ViewModel을 사용하는 것을 권장하고, 데이터가 애플리케이션 데이터라면 디스크에 저장하는 영구 스토리지를 권장합니다.

 

감사합니다.

 

 

참고

 

https://developer.android.com/guide/components/activities/activity-lifecycle

 

활동 수명 주기에 관한 이해  |  Android 개발자  |  Android Developers

활동은 사용자가 전화 걸기, 사진 찍기, 이메일 보내기 또는 지도 보기와 같은 작업을 하기 위해 상호작용할 수 있는 화면을 제공하는 애플리케이션 구성요소입니다. 각 활동에는 사용자 인터페

developer.android.com

 

https://developer.android.com/guide/components/activities/state-changes

 

활동 상태 변경 처리  |  Android 개발자  |  Android Developers

활동은 사용자가 전화 걸기, 사진 찍기, 이메일 보내기 또는 지도 보기와 같은 작업을 하기 위해 상호작용할 수 있는 화면을 제공하는 애플리케이션 구성요소입니다. 각 활동에는 사용자 인터페

developer.android.com

 

https://developer.android.com/topic/libraries/architecture/saving-states

 

UI 상태 저장  |  Android 개발자  |  Android Developers

구성 변경 시 UI 상태를 유지하는 방법을 알아봅니다.

developer.android.com

 

 

코드

 

https://github.com/tekken5953/SavedInstanseStateExam

 

GitHub - tekken5953/SavedInstanseStateExam

Contribute to tekken5953/SavedInstanseStateExam development by creating an account on GitHub.

github.com