BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Airbnb Open-Sources MvRx for Android App Development in Kotlin

Airbnb Open-Sources MvRx for Android App Development in Kotlin

This item in japanese

MvRx (pronounced "mavericks") helps Android developers implement common features and integrate their apps properly with the OS by providing a reactive app development framework. MvRx is written in Kotlin and powers all Android development at Airbnb, writes Airbnb engineer Gabriel Peal. The framework aims to reduce the code app developers needs to write, up to 50–75%, according to Peal.

MvRx is based on four basic concepts:

  • Immutable state, which is used to render the UI. State properties are instances of Observable<T> and can therefore be used to trigger certain operations whenever they change.
  • Views, which are rendered each time a property of their associated state changes. Views can be considered ephemeral objects that are created each time their invalidate method is called. Views can be associated to Fragments and responds to the Android lifecycle. A View is associated to one or more ViewModels.
  • ViewModels, which own the state and are used to handle the business logic of the app. ViewModels are the only objects that can modify state using setState, which returns a new state from the current one using Kotlin’s copy mechanism. ViewModels can access their state using withState blocks, which are guaranteed to be executed only after all pending setState operations have completed. As mentioned, you can subscribe to state changes in a ViewModel.
  • Async operations, which can be associated to State property so each time a state property changes, the associated operation is carried through. Async is a sealed class with four subclasses: Uninitialized, Loading, Success, and Fail.

The following is a minimalist example of a cluster of MvRx classes that fire a network request, handles loading state, display the results, handle rotation and configuration changes:

data class MyState(val listing: Async<Listing> = Uninitialized) :
MvRxState

class MyViewModel(override val initialState: MyState) : MvRxViewModel<MyState>() {
    init {
        fetchListing()
    }

    private fun fetchListing() {
        ListingRequest.forId(1234).execute { copy(listing = it) }
    }
}

class MyFragment : MvRxFragment() {
    private val viewModel by fragmentViewModel(MyViewModel::class)

    override fun epoxyController() = simpleController(viewModel) { state ->
        if (listing() == null) {
            loaderRow()
            return
        }
        
        header {
            title(listing.title)
        }
        // Put the rest of your epoxy models here...
    }
}

The example above uses Epoxy, another framework from Airbnb useful to building complex screens in a RecyclerView.

There are many more aspects to consider to use MvRx at its full potential, including threading, persistence, debug facilities, so do not miss the official documentation wiki.

Rate this Article

Adoption
Style

BT