안드로이드 26) MVVM 모델
MVVM 모델
1. Android MVVM
- MVVM : AAC의 핵심 아키텍처
- M(Model) : 업무로직에 의해 데이터가 발생되거나 데이터를 관리하는 부분
- V(View) : 화면
- VM(ViewModel) : Model과 View를 분리시키기 위한 역할자
- View가 ViewModel을 실행시키면 ViewModel이 업무가 진행되는 Model을 실행시키고, Model에 의한 결과를 ViewModel이 받아 View에서 이용
- 어플리케이션은 Separation of concerns에 의해 작성되는 것이 권장된다
- 그로 인해 UI와 모델이 분리
2. AAC의 핵심 요소를 사용해서 개발시 전체적인 구조
1) Activity / Fragment : View
- UI를 구성하고 유저와 상호 작용, LifeCycle 변경을 감지
- LifeCycle 변경이 발생하면 ViewModel에 전달
- ViewModel에서 전달한 LiveData의 내용을 화면에 출력
- Activity나 Fragment에 가장 중요한 업무 로직은 이벤트를 처리인데 서버 데이터를 받다 보면 시간이 걸릴 수 있음
- 이를 해결하기 위해 ViewModel에 요청해서 업무로직이 실행된 결과값을 LiveData로 받아내자
2) ViewModel : View와 Model을 분리
- View와 Model을 분리시키기 위한 가교 역할
- View의 LifeCycle 변경을 감지하고 변경이 발생하면 적절한 Repository를 실행시켜 업무가 진행되도록 함
- Repository에서 발생한 LiveData를 View에 전달
3) Repository : 데이터 처리
- 데이터의 저장 및 획득이 주 목적
- Repository가 서버(WebServices)인 경우 Repository에 Retrofit 코드 작성
- Repository가 DB인 경우 Room 이용
ViewModel
1. ViewModel
- MVVM의 핵심은 화면에서 비즈니스 업무 로직을 분리해서 개발하는 것
- Activity, Fragment에서 UI를 처리하고 ViewModel에서 비즈니스 업무 로직을 처리
- Activity에서 onSaveInstanceState() 함수를 이용해 작성하는 Bundle 데이터 저장도 ViewModel로 대체가 가능
2. ViewModel 사용 방법
1) build.gradle 추가
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
2) ViewModel 상속으로 작성
class MyViewModel: ViewModel() {
val user: MutableLiveData<User>
get() {
val user = MutableLiveData<User>()
user.postValue(User("gildong", "hong1"))
return user
}
}
3) Activity에서 ViewModel 이용
val model = ViewModelProvider(this).get(MyViewModel::class.java)
model.user.observe(this, {
binding.textView.text = "${it.firstName} - ${it.lasgName}"
})
- ViewModelProvider를 이용한 객체 생성하고 ViewModel의 함수를 호출
- 직접 객체 생성도 가능(비추천, Bundle 데이터 저장이 불가)
- ViewModelProvider을 이용한 객체를 생성해야 Activity 상태 변화에 따른 ViewModel이 재생성되는 것을 막고, 데이터를 유지할 수 있음
implementation "androidx.activity:activity-ktx:$activity_version"
val model: MyViewModel by viewModels()
- ViewModelProvider를 이용해 객체를 생성하는 것을 단순화 시킨 delegator
3. ViewModel Lifecycle
- Activity가 상태 변화할 때, ViewModel은 종료되지 않아 데이터를 유지하고 ViewModel이 재생성되는 것을 막을 수 있다
- Activity가 최종 종료 되면 ViewModel도 종료
- Activity Scopte 내에서 Singleton
4. AndroidViewModel
- AndroidViewModel은 ViewModel의 서브 클래스
- ViewModel 내에서 application 객체를 이용하고자 할 때 AndroidViewModel 상속 받아서 사용
- ViewModel()
- AndroidViewModel(Application application)
5. Fragment에서 ViewModel 이용
- Activity 내에 Fragment가 여러 개 있는 경우 Lifecycle Owner를 누구에게 주는가에 따라
- 각 Fragment가 각각의 ViewModel을 가져 Fragment와 ViewModel의 Lifecycle이 같이 가게 할 수도 있고
- Fragment간 ViewModel 공유할 수도 있다
val model = ViewModelProvider(requireActivity()).get(MyFragmentViewModel::class.java)
- Fragment간에 ViewModel을 공유하게 할 경우 함수의 매개변수에 Activity를 주어 ViewModel의 Owner를 Activity로 변경
LiveData
1. LiveData
class MyViewModel: ViewModel() {
// String 데이터 리턴, 뷰가 결과값이 넘어올 때까지 대기 상태에 빠짐
fun someData(): String {
return "hello"
}
// livedata 리턴, 비동기적으로 데이터를 받을 수 있음
fun someData2(): MutableLiveData<String> {
val liveData = MutableLiveData<String>()
thread {
SystemClock.sleep(3000)
liveData.postValue("world")
}
return liveData
}
}
- ViewModel의 결과
- ViewModel에서 String 등의 결과를 리턴시킬 수도 있지만 LiveData를 리턴 시켜 Observer로 결과 이용
2. Observer
val observer = object : Observer<String> {
override fun onChanged(t: String?) {
Log.d("min", "onChanged... $t")
}
}
model.someData2().observe(this, observer)
val liveData = model.someData2()
...
liveData.removeObservers(this)
- LiveData의 변경을 감지하는 observer는 Observer를 구현한 클래스
- LiveData의 값이 변경되면 Observer의 onChanged() 함수가 자동 호출
- 더 이상 감지가 필요 없는 경우 명시적으로 removeObservers 함수 호출
3. Custom LiveData
class MyLiveData: LiveData<String>() {
fun sayHello(name: String) {
postValue("Hello $name")
}
}
val liveData1 = MyLiveData()
liveData1.observe(this) {
Log.d("min", "result : $it")
}
liveData1.sayHello("min")
- LiveData를 상속받아 작성
- ViewModel 이외에 다른 곳에서 사용 가능
Author And Source
이 문제에 관하여(안드로이드 26) MVVM 모델), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@alsgk721/안드로이드-26-MVVM-모델저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)