MvRx(“マーベリクス”と読む)は、Android開発における共通的な機能の実装と、アプリのOSへの適切な統合を支援するフレームワークだ。MvRx自体はKotlinで記述されており、AirbnbのエンジニアであるGabriel Peal氏によれば、AirbnbのすべてのAndroid開発者が利用している。
MvRxは、リアクティブなフレームワークの提供によって、記述の必要なコードを50~70パーセント削減することを目標とする。MvRxには4つの基本的な概念がある。
- UIのレンダリングに使用されるイミュータブルなState。Stateプロパティは
Observable<T>
のインスタンスであるため、変更時に特定の操作をトリガする目的で使用できる。 - 関連するStateのプロパティが変更される度にレンダリングされるView。
invalidate
メソッドのコール毎に生成されるエフェメラル(ephemeral)オブジェクトと見なすことができる。ViewはFragmentに関連付けられ、Androidライフサイクルに対応する。さらにViewは、ひとつ以上のViewModelに関連付けられる。 - 自身で状態を持ち、アプリのビジネスロジック処理に使用されるViewModel。ViewModelは
setState
を使って状態を変更可能な唯一のオブジェクトで、Kotlinのcopy
メカニズムを使って、現在の状態から新たな状態を返す。withState
ブロックを使うことで、ViewModelの状態にアクセスできる。withStateブロックは、保留中のすべてのsetState
操作が完了した後にのみ実行されることが保証されている。前述のように、ViewModelの状態変化をサブスクライブすることも可能だ。 - Stateプロパティに関連付け可能なAsync操作。Stateプロパティが変更されると、関連する操作が実行される。Asyncはシールドクラスで、
Uninitialized
,Loading
,Success
,Fail
という4つのサブクラスを持つ。
以下にあげたのは、ネットワーク要求の発行、ローディング状態の処理、結果の表示、ローテーションと設定変更の処理を行なう、MvRxクラスによるクラスタの最小限の例である。
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...
}
}
この例では、RecyclerView
内に複雑な画面を構築する場合に便利な、AirbnbのもうひとつのフレームワークであるEpoxyも使用されている。
MvRxを最大限に活用するためには、他にもスレッディングやパーシステンス、デバッグ機能など、考慮すべき側面が多数あるので、公式のドキュメントWikiを必ず参照して頂きたい。
この記事を評価
- 編集者評
- 編集長アクション