【Kotlin】초보자용: 화면 회전이나 수면 후의 UI 유지

소개



이번은 화면을 회전시켰을 때나 본체를 슬립시킨 후, 뷰의 일부가 그 전후로 바뀌어 버리는 문제에 대해 임합니다. 아래의 간단한 버튼 카운터 앱으로 그 모습을 확인할 수 있습니다. 세로 화면에서 카운트 업시켰을 때 옆으로 전환하면 숫자가 0으로 돌아 버립니다.



원인



이 문제의 원인은, 화면의 방향을 바꾸는 등의 여러가지 동작에 의해, Activity가 라이프 사이클을 처음부터 다시 하는 것입니다. 이로 인해 하드웨어는 유연하고 신속하게 사용자의 액션을 반영시킬 수 있지만 동시에 UI까지도 파기되어 초기화되어 버립니다. 이를 막기 위해서는 라이프사이클이 끝나기 전에 UI 등의 필요한 정보를 일시적으로 유지해 둘 필요가 있습니다.

*라이프 사이클에 대해서는 이쪽: htps : // m / K4 4 / ms / 2f4 2 bab b67 cf89

onSaveInstanceState



일시적으로 정보를 유지하는 방법 중 하나는 onSaveInstanceState를 사용하는 것입니다. 이 방법은 별로 대용량이 아닌 정보를 쉽게 보관할 때 이용합니다. 사용법은 매우 간단합니다.
override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)

        outState?.putInt("key", i)
    }

    override fun onRestoreInstanceState(savedInstanceState: Bundle) {
        super.onRestoreInstanceState(savedInstanceState)

        i = savedInstanceState?.getInt("key", 0)
        textView.text = i.toString()
    }
onSaveInstanceState 메소드(데이터를 보관 유지한다)와 onRestoreInstanceState 메소드(보존한 데이터를 복원한다)를 호출해, put〇〇get〇〇 로 실제로 데이터의 전달을 실시하고 있습니다.onSaveInstanceState 메소드의 outState?.putInt("key", i) 라는 것은 outState (데이터를 메모리에 보존하는 실체)에 "key"(선택)이라고 하는 키를 사용해, i 라고 하는 Int 의 값을 보관 유지한다. 라는 것을 가리키고 있습니다. 열쇠는 그 이름대로 열쇠입니다. 호출측과 공통의 키를 가지지 않으면, 데이터의 전달은 할 수 없습니다.onRestoreInstanceState 메소드의 i = savedInstanceState?.getInt("key", 0) 는 Activity가 파기되어 값이 초기화되어 버린 i 에 보관 유지한 데이터의 실태 savedInstanceState . getInt 의 제 2 인수는 getInt 가 null 의 경우의 값을 설정합니다.
이 두 가지 방법과 그 내용을 넣는 것만으로 간단하게 설정한 값을 유지할 수 있습니다.

onSaveInstanceState 및 onRestoreInstanceState 및 수명 주기



위에서 언급했듯이이 두 가지 방법을 사용하면 쉽게 UI를 유지할 수 있습니다. 그렇다면이 두 가지 방법은 Activity의 라이프 사이클에서 어떤 단계에서 작동합니까?

그것을 보여주는 것이이 그림입니다. 이 그림은 Activity의 기본적인 공정에 이번에 사용한 두 가지 방법 등을 더한 것입니다. 이 그림과 같이 putInt는 onPause 다음에 값을 유지하고 onSaveInstanceStateonRestoreInstanceState 다음에 값을 복원합니다. onStart 의 값은 onRestoreInstanceState 에 영향을 미치지 않거나 onCreate 가 호출되면 반드시 앱이 멈추는 것 등을 알 수 있습니다.

실제로이 라이프 사이클을 시각화 해보십시오.


class MainActivity : AppCompatActivity() {

    private var i : Int = 0

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

        button.setOnClickListener {
            i += 1
            textView.text = i.toString()
        }
    }

    override fun onStart() {
        Log.d(TAG, "onStart: called")
        super.onStart()
    }

    override fun onResume() {
        Log.d(TAG, "onResume: called")
        super.onResume()
    }

    override fun onPause() {
        Log.d(TAG, "onPause: called")
        super.onPause()
    }

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

        outState.putInt("key", i)
    }

    override fun onRestoreInstanceState(savedInstanceState: Bundle) {
        Log.d(TAG, "onRestoreInstanceState: called")
        super.onRestoreInstanceState(savedInstanceState)

        i = savedInstanceState.getInt("key", 0)
        textView.text = i.toString()
    }

    override fun onStop() {
        Log.d(TAG, "onStop: called")
        super.onStop()
    }

    override fun onRestart() {
        Log.d(TAG, "onRestart: called")
        super.onRestart()
    }

    override fun onDestroy() {
        Log.d(TAG, "onDestroy: called")
        super.onDestroy()
    }
}

MainActivity의 내용을 이와 같이 하는 것으로, 실제로 어디에서 데이터의 유지등이 행해지고 있는지 로그를 통해서 가시화할 수가 있습니다. 이 소스 코드는 위에서 설명한 카운트 업 기능을 위해 데이터를 교환합니다. 잘하면 각 공정마다 로그에 출력이 이루어집니다. 꼭 회전 등시켜 시도해보십시오.

좋은 웹페이지 즐겨찾기