안드로이드 앱 개발을 하다보면, 화면 회전이나 생명주기 변화에 따른 데이터 유지를 위해 ViewModel을 사용합니다. 이 때, ViewModel의 사용범위에 따라 by activityViewModels()
, by viewModels()
, ViewModelProvider
등 다양한 방법으로 ViewModel을 선언할 수 있습니다.
by activityViewModels()
는 액티비티 범위의 ViewModel
을 제공합니다. 즉, 한 액티비티 안에 여러 프래그먼트가 있다면, 이 프래그먼트들 사이에서 ViewModel
을 공유할 수 있습니다.
class MainActivity : AppCompatActivity() {
private val viewModel: MainViewModel by activityViewModels()
...
}
위의 코드에서 by activityViewModels()
를 사용하면, MainActivity
와 그 안의 모든 프래그먼트에서 같은 MainViewModel 인스턴스에 접근할 수 있습니다.
by viewModels()
는 프래그먼트 범위의 ViewModel
을 제공합니다. 즉, 해당 프래그먼트에서만 ViewModel을 사용하게 됩니다.
class MainFragment : Fragment() {
private val viewModel: MainViewModel by viewModels()
...
}
위의 코드에서 by viewModels()
를 사용하면, MainFragment
에서만 MainViewModel
을 사용할 수 있습니다. 다른 프래그먼트나 액티비티에서는 MainFragment
의 MainViewModel
에 접근할 수 없습니다.
하지만, by viewModels()
를 액티비티에서 사용하는 경우에도 ViewModel
의 생명주기는 해당 액티비티에 결부됩니다.
class MainActivity : AppCompatActivity() {
private val viewModel: MainViewModel by viewModels()
...
}
위의 코드에서 by viewModels()
를 사용하면, MainActivity
에서 MainViewModel
을 사용할 수 있지만, 이 액티비티에 포함된 프래그먼트에서는 MainViewModel
에 접근할 수 없습니다
ViewModelProvider
를 사용하면 ViewModel
의 인스턴스를 직접 생성하고 관리해야 합니다.
class MainActivity : AppCompatActivity() {
private lateinit var viewModel: MainViewModel
...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
}
}
위의 코드에서는 viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
처럼 직접 초기화해야 합니다. ViewModelProvider
를 사용한 경우에는 by activityViewModels()
나 by viewModels()
와 달리 ViewModel
의 생명주기를 개발자가 직접 관리해야 합니다. 또한, ViewModelProvider
를 사용하면 ViewModel
의 범위는 ViewModelProvider
의 파라미터로 전달된 this
의 범위에 따라 결정됩니다.