Activity LifeCycle을 보면 Activity를 가로 세로 회전시킬 때 onDestroy() 호출되고, 다시 onCreate()가 생성된다.
즉, 종료됐다가 새로 생성되는 것이다.
이때 기존 Activity가 가지고 있던 데이터들은 당연히 사라지게 된다.
예를 들어 버튼을 클릭할 때마다 count 변수가 증가한다고 하자.
아무 처리없이 count를 어느 정도 증가를 시킨 후, 화면을 회전시키면 count는 0이 된다.
이를 화면에 뛰운다면 7이었던 count가 회전을 시켰더니 0이 화면에 보이게 된다는 것이다.
이를 해결하기 위한 방법은 2가지가 있다.
- Manifest 수정
- onSaveInstanceState()와 onRestoreInstanceState() 사용
이 두가지 방법에 대해 알아보자.
Manifest 수정
정말 간단하고 쉬운 방법이다.
Manifest의 activity에 android:configChanges="orientation|screenSize"를 추가시켜주면 된다.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.myapplication">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyApplication">
<activity
android:name=".MainActivity"
android:exported="true"
android:configChanges="orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
하지만 이 방법은 추천하지 않는다.
화면을 제어하는 것으로 우리가 한 개의 액티비티만을 제어할 것이면 문제가 되지 않겠지만, 앱은 여러 액티비티와 프래그먼트로 구성되어 있다.
화면 전환을 할 때, 이들이 모두 같은 동작을 하는 게 아닐 수 있어 개발 중 문제를 일으킬 수 있다.
onSaveInstanceState()와 onRestoreInstanceState() 사용
이 방법은 Activity LifeCycle을 따르는 방법이다.
화면을 회전할 때의 호출 순서는 다음과 같다.
onPause() → onSaveInstanceState() -> onStop() → onDestroy() → onCreate() → onStart() → onRestoreInstanceState() → onResume()
onSaveInstanceState()은 파라미터로 outState: Bundle을 받는다.
Bundle은 객체에 Activity의 상태에 대한 데이터를 (key, value) 형태로 받는다.
주의할 점으로는 onSaveInstanceState 콜백에 두 가지 종류가 있다는 것이다.
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
}
override fun onSaveInstanceState(outState: Bundle, outPersistentState: PersistableBundle) {
super.onSaveInstanceState(outState, outPersistentState)
}
파라미터를 두 개받는 onSaveInstanceState에서 두 번째 파라미터인 outPersistentSate: PersistableBundle은 명시적인 Acitivity에서만 호출이 된다. 딱히 쓸 일이 없으므로 override를 할 때 outState: Bundle만 파라미터로 받는 onSaveInstanceState()를 사용하도록 하자.
이제 onSaveInstanceState(outState: Bundle)에서 Bundle에 저장한 값을 가져와야 한다.
이는 onRestoreInstanceState()에서 진행하게 된다.
이것 또한 파라미터가 한개인 것과 두 개인 것으로 나눠져 있다. 한 개인 것을 사용하자.
onRestoreInstanceState()는 saveInstanceState: Bundle을 파라미터로 받는다.
즉 Bundle에 있는 값을 꺼내면 된다.
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
val count = savedInstanceState.getInt("count")
}
예시에서 우리는 정수형인 count를 들었으므로 여기서는 count = saveInstanceState.getInt("key")가 되게 된다.
예시에서 들었던 것을 코드로 보면 다음과 같이 된다.
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putInt("count", count)
}
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
numberTextView.text = savedInstanceState.getInt("count").toString()
}
'Android' 카테고리의 다른 글
[Android] RecyclerView(리사이클러뷰) (0) | 2022.08.20 |
---|---|
[Android] AlertDialog를 이용한 알림 창 띄우기 (0) | 2022.08.17 |
[Android] Fragment와 Fragment 생명 주기 (0) | 2022.08.15 |
[Android] Activity LifeCycle(액티비티 생명주기) (0) | 2022.08.14 |
[Android] Toast Message(토스트 메세지) (0) | 2022.08.14 |
댓글