×

Airbnb Open-sources MvRx for Android App Development in Kotlin

MMS Founder
MMS RSS

Article originally posted on InfoQ. Visit InfoQ

MvRx (pronounced “mavericks”) help Android developers implement common features and integrating their apps properly with the OS. MvRx is written in Kotlin and powers all Android development at Airbnb, writes Airbnb engineer Gabriel Peal.

MvRx provides a reactive app development framework that aims to reduce the code developers needs to write, up to 50–75% Peal says. It 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.

Subscribe for MMS Newsletter

By signing up, you will receive updates about our latest information.

  • This field is for validation purposes and should be left unchanged.