ABOUT ME

-

  • Android) 새로워진 Mavericks 2.0을 알아보자
    Android 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

    airbnb mavericks

    Introducing Mavericks

    Maverics Architecture

    Mavericks

    반응형

    댓글

Designed by Me.