viewModelScope.launch {
//TODO asynchronous
}
일반적으로 알고 있는 Activity나 Fragment의 생명주기와 ViewModel의 생명주기는 차이가 있다.
Activity 생성 시 ViewModel을 인스턴스화하여 생명주기가 함께 시작된다.
Activity의 경우에는 구성 변경이 일어날 때 재시작하는 것을 확인할 수 있으나, ViewModel의 경우에는 메모리 상에 계속 유지된다.
ViewModel은 Activity의 구성 변경과는 무관하게 유지되는 NonConfigurationInstances 객체를 따로 관리하기 때문이다.
Activity의 생명주기가 finish()를 통해 실질적으로 종료됨에 따라 내부의 LifeCycleEventObserver를 통해 ViewModel도 onCleared()를 통해 같이 종료된다.
1. ViewModelProvider를 통해 ViewModel 인스턴스를 요청한다.
2. Provider 내부에서는 ViewModelStoreOwner를 참조하여 ViewModelStore를 가져온다.
3. ViewModelStore에게 생성 또는 저장된 ViewModel 인스턴스를 요청한다.
4. 만일 ViewModelStore가 적합한 ViewModel 인스턴스를 갖고 있지 않다면, Factory를 통해 ViewModel 인스턴스를 생성한다.
5. 생성한 ViewModel 인스턴스를 Store에 저장하고 해당 인스턴스를 Client에게 반환한다.
/*
currentName 이라는 변수가 값을 Observe할 대상으로 만들어질 것이다.
여기에서 MutableLiveData 라는 클래스가 쓰였는데,
이 클래스는 Observer Pattern과 비슷한 역할을 가지는 클래스이다.
ViewModel에서 사용하는 데이터는 이 클래스의 생성자를 통해 만든다고 이해하면 된다.
*/
class NameViewModel : ViewModel() {
val currentName : MutableLiveData<String> by lazy {
MutableLiveData<String>()
}
.
.
.
class MainActivity : AppCompatActivity() {
private lateinit var model : NameViewModel
private lateinit var binding : ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
model = ViewModelProvider(this).get(NameViewModel::class.java)
binding.name = model
model.currentName.observe(this, Observer {
binding.textOutput.text = it.toString()
})
binding.btnSave.setOnClickListener {
binding.textOutput.text = binding.editName.text.toString()
binding.editName.text.clear()
}
}
}
class MyViewModel : ViewModel() {
val message = MutableLiveData<String>()
fun sendMessage(text: String) {
message.value = text
}
}
.
.
.
//ViewModel 데이터 업데이트
class FirstFragment : Fragment() {
lateinit var model: MyViewModel
//...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
model = ViewModelProvider(requireActivity()).get(MyViewModel::class.java)
button.setOnClickListener { model.sendMessage("MindOrks") }
}
}
.
.
.
//ViewModel 데이터 Detecting
class SecondFragment : Fragment() {
// ...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val model = ViewModelProvider(requireActivity()).get(MyViewModel::class.java)
model.message.observe(viewLifecycleOwner, Observer { textViewReceiver.text = it })
}
}
참고 자료 :