앱이 강제 종료 될 경우 대비
바로 앱이 강제 종료 될 경우의 대비 방법을 알아보겠다.
여담으로, 메모리 부족 등의 이유로 시스템이 앱을 강제종료할 겨ㅇ우에는 뷰모델은 데이터를 유지할 수 없다.
savedStateHandle 사용
이 방법은 앞전 글에도 설명했지만, RAM에 데이터를 저장하기 때문에 많은 데이터를 저장할 수는 없다. 하지만 시스템에 의한 강제종료에도 데이터를 유지할 수 있다.
https://developer.android.com/topic/libraries/architecture/saving-states#onsaveinstancestate
이 방법은 거의 모든 코틀린 데이터 타입을 저장할 수 있다.
또, saveState에는 Key:Value 형태로 값을 저장한다.(Map이요)
자 그럼, 지난 글의 counter가 강제 종료 후에도 값이 유지될 수 있도록 만들어 보겠다.
app gradle: dependency 추가
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.5.1'
ViewModel에서 savedStateHandle을 설정
class MyViewModel(
_counter: Int,
private val savedStatedHandle: SavedStateHandle // 생성자에 포함된다.
): ViewModel() {
// count 값 가져오기
// 1. 기본적으로 savedStateHandle을 통해 가져옴
// 2. 저장된 값이 없을 경우, 전달받은 초기값을 사용함
var counter = savedStatedHandle.get<Int>(SAVE_STATE_KEY) ?: _counter
// count 값 저장
fun saveState() {
savedStatedHandle.set(SAVE_STATE_KEY, counter)
}
// saveState 저장/복원에 사용할 key 값 정해준다.
companion object{
private const val SAVE_STATE_KEY = "counter"
}
}
ViewModel 초기값으로 saveStateHandle이 추가되었으니, Factory 클래스도 수정해 준다.
Factory class 수정
@Suppress("UNCHECKED_CAST")
class MyViewModelFactory(
private val counter: Int,
owner: SavedStateRegistryOwner,
defaultArgs: Bundle? = null
): AbstractSavedStateViewModelFactory(owner,defaultArgs) {// 상속하는 Factory가 달라졌다.
override fun <T : ViewModel?> create(
key: String,
modelClass: Class<T>,
handle: SavedStateHandle // SavedStateHandle을 받을 수 있게 됨
): T {
if(modelClass.isAssignableFrom(MyViewModel::class.java)){
return MyViewModel(counter,handle) as T // viewModel에게 SavedStateHandle을 넘겨줌
}
throw IllegalArgumentException("viewModel class not found")
}
}
마지막으로 액티비티 코드를 수정해준다.
Activity 코드 수정
class MainActivity : AppCompatActivity() {
private val binding: ActivityMainBinding by lazy {
ActivityMainBinding.inflate(layoutInflater)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
Log.d("onCreate", "onCreate")
val factory = MyViewModelFactory(100, this) // factory에 SavedStateRegisterOwner를 전달
val myViewModel by viewModels<MyViewModel> {factory}
binding.textView.text = myViewModel.counter.toString()
binding.button.setOnClickListener {
myViewModel.counter += 1
binding.textView.text = myViewModel.counter.toString()
myViewModel.saveState() // 값을 증가시킬 때마다 savedStateHandle에 저장한다.
}
}
}
Uploaded by
N2T'Android > Basic' 카테고리의 다른 글
[Android: Jetpack] LiveData & Observer Pattern (0) | 2023.01.17 |
---|---|
[Android: Jetpack] Architecture Pattern과 Android App Architecture (1) | 2023.01.12 |
[Android: Jetpack] ViewModel & Lifecycle 기초(1) (0) | 2022.12.31 |
[Android: Jetpack] 안드로이드 AAC(Android Architecture Components) 간략한 정리 (0) | 2022.12.31 |
[Android: Jetpack] ViewBinding 기초 (0) | 2022.12.31 |