onCreate에서 작업을 처리해야 하므로 UI 컨트롤러가 해야 할 일이 늘어나며 화면을 띄우는데 시간이 오래 걸린다.
- ViewModel
ViewModel을 상속받는 클래스를 만들어 데이터를 저장하고 관리하는 로직을 간단하게 구현하였다.
class MyViewModel : ViewModel() {
private val users: MutableLiveData<List<User>> by lazy {
MutableLiveData().also {
loadUsers()
}
}
fun getUsers(): LiveData<List<User>> {
return users
}
private fun loadUsers() {
// Do an asynchronous operation to fetch users.
}
}
이렇게 생성된 ViewModel은 액티비티 혹은 프래그먼트와 다른 생명주기를 가지게 된다.
뷰모델은 범위가 지정된 LifeCycle이 영구적으로 경과될 때까지, 즉 액티비티에선 액티비티가 끝날 때까지, 그리고 프래그먼트에선 프래그먼트가 분리될 때까지 메모리에 남아 있다.
즉, 생명 주기가 더 길다는 뜻이다.
finish 메서드가 호출됐을 때, 혹은 사용자가 직접 뒤로 가기 버튼을 눌러 액티비티를 종료했을 때, onCleared 메서드를 통해 ViewModel은 비로소 소멸이 된다.
이 부분은 ViewModelProvider를 사용할 때 this를 넘겨주는 데 이는 owner를 의미한다.
ViewModelStore를 누가 소유하고 있느냐? -> this가 소유하고 있다 = MainActivity가 소유하고 있다.
그렇다면 ViewModelStore은 무엇일까?
ViewModelStore은 ViewModel 객체가 HashMap 구조로 저장되는 곳이다.
즉, get() 안에 있는 'UserViewModel..'은 객체를 찾아오기 위한 Key값으로 쓰이는 것이다.
그림으로 설명하자면 이렇다.
뷰 모델을 HashMap 구조로 저장하니까 get() 메서드에 Key값을 넣어준 거고.
(만약 Key에 해당하는 Value가 없으면 생성하고 가져온다. 그래서 처음 뷰 모델 객체를 처음 만드는데도 set 따위가 아니라 get을 쓰는 것)
저 ViewModelStore를 소유하고 있는 주체가 MainActivity라는 것을 알려주는 것이다.
이를 통해 우리는 2가지 사실을 알 수 있다
뷰 모델을 각각 다른 소유자가 생성하면 이는 별개의 메모리 공간을 사용하는 다른 객체가 된다.
하나의 액티비티를 소유자로 지정해 사용하면 같은 ViewModel을 공유할 수 있다. = 데이터 공유 가능
feat) ❗❗
#위에 코드 두줄과 아래 코드 한줄이 같은 의미
private lateinit var userViewModel: UserViewModel
userViewModel = ViewModelProvider(this).get(UserViewModel::class.java)
private val model: UserViewModel by viewModels()
공식문서를 보니 뷰모델 객체를 생성하는 위에 두 줄을 아래 한 줄처럼 사용해도 된다고 한다.