Android
Android) 새로워진 Mavericks 2.0을 알아보자
가짜 개발자
2021. 9. 22. 19:40
이전에 MvRx에 대한 포스팅을 했습니다.
오늘은 Mavericks 2.0에 대한 내용입니다.
Mavericks
- 개별적인 상태 속성을 노출하는 대신, 하나의 불변 데이터 클래스를 사용해 뷰모델을 업데이트하고 UI를 렌더링 합니다.
- Mavericks 1.0은 RxJava 기반으로 되어 있었는데, Mavericks 2.0에서 Coroutines로 새롭게 작성되었습니다.
- MVI 프레임워크로 상태 관리를 쉽게 처리하기 위해 Airbnb에서 만든 기술입니다.
- Coroutines, Dagger, Hilt, Jetpack Compose, Jetpack Navigation 등을 지원합니다.
What is MVI?
- Model - 상태를 나타낸다. MVI에서 Model은 데이터 플로우가 단방향으로 이루어지기 위해 불변성을 보장해야 한다.
- View - View는 Activity / Fragment를 나타내며, 상태를 전달받아 화면에 렌더링 한다.
- Intent - 앱 / 사용자가 취하는 행위를 나타내기 위한 의도. View는 Intent를 받고, ViewModel은 Intent를 관찰하여 Model은 그에 따른 새로운 상태로 변환.
Add The Dependency
dependencies {
implementation 'com.airbnb.android:mavericks:x.y.z' // 2.0.0
}
Core Concept
- MavericksState
- MavericksViewModel
- MavericksView
MavericksState
1. UI를 렌더링 하는데 도움이 되는 모든 속성이 있습니다.
- Thread Safe
- Koltin Data Class
- Immutable Properties
- 초기 상태를 전달하기 위한 default value를 가지고 있습니다.
- state는 Kotlin Data Class이기 때문에, 파생 속성을 만들 수 있습니다.
data class UserState(
val name: String = "사용자",
val age: Int = 29,
val regionName: String = "정릉4동",
val profileImageUrl: String? = null
) : MavericksState {
// Derived Properties
val introduction: String
get() = "이름:$name, 나이:$age, 사는곳:$regionName"
}
MavericksViewModel
1. 상태 업데이트
2. 다른 클래스들이 관찰할 수 있는 상태 스트림 노출
- MavericksViewModel은 화면 회전, LMK 등의 Configuration Changes가 발생할 때, 데이터를 유지하기 위해서 Jetpack ViewModel을 구현하는 형태로 되어 있습니다.
- 일반적인 ViewModel은 내부에 LiveData, MutableLiveData를 생성하고 이를 framgent/activity에 보여주는 방식인 반면, MavericksViewModel은 하나의 Immutable Data Class(state class)를 가지고, 하나의 data class만 업데이트하고 UI를 렌더링 합니다.
- StateFlow를 사용해서 stream으로 상태를 구독할 수 있는 메서드 제공
- 상태는 기본적으로 Immutable이라 직접 변경할 수 없습니다. 대신 setState 함수를 사용하여 상태를 업데이트합니다.
- Kotlin Data Class에서 제공하는 copy() 메서드를 사용하여 속성을 업데이트합니다.
class UserViewModel(initialState: UserState) :
MavericksViewModel<UserState>(initialState) {
fun getIntroduction() = setState {
copy(name = "이름:$name, 나이:$age, 사는곳:$regionName")
}
}
MavericksView
- MavericksView는 실제로 데이터를 렌더링 하는 곳입니다.
1. ViewModel delegates를 통해 MavericksViewModel에 접근할 수 있습니다.
2. invalidate() 메서드를 Override합니다. 상태 변경 시 UI를 다시 그리는데 사용됩니다.
- withState() 메소드를 사용해 state observer를 구현하고, 이를 기반으로 UI를 업데이트합니다.
- withState() 메서드는 단일 ViewModel에서 ViewModel의 상태에 동기적으로 접근하고 block의 결과를 반환합니다.
class UserFragment : Fragment(R.layout.fragment_user), MavericksView {
private lateinit var binding: FragmentUserBinding
private val viewModel: UserViewModel by fragmentViewModel()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentUserBinding.bind(view)
binding.imageProfile.setOnClickListener {
viewModel.getIntroduction()
}
}
override fun invalidate() = withState(viewModel) { state ->
// Update your views with the latest state here.
// This will get called any time your state changes and the viewLifecycleOwner is STARTED.
with(binding) {
textName.text = state.name
textAge.text = state.age.toString()
textRegion.text = state.regionName
}
}
}
※ Application 클래스를 만들고 Mavericks를 초기화해줘야 합니다.
- 초기화해주지 않으면 IllegalStateException이 발생합니다.
class UserApplication : Application() {
override fun onCreate() {
super.onCreate()
Mavericks.initialize(this)
}
}
// AndroidManifest.xml
<application
android:name=".UserApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name">
Preferences
반응형