okuzawatsの日記

Android / Kotlin / GitHub Actions Enthusiast 🤖

[Android] Uniflowを用いたMVI的なアーキテクチャを試してみる🦄

目次

MVI的な単一方向のデータフローをサポートするライブラリUniflowを(しばらく前に)試してみました。その概要はWhat is Uniflow?に詳しいです。

Uniflow 🦄 - Simple Unidirectional Data Flow for Android & Kotlin, using Kotlin coroutines and open to functional programming https://github.com/uniflow-kt/uniflow-kt

ここ1年ほどはコミットが進んでないようです。最新バージョンは1.1.2で、1.1.1とかなり違うような…。

dependencies {
  implementation 'org.uniflow-kt:uniflow-android:1.1.2'
}

Uniflowを味見してみる

io.uniflow.android.AndroidDataFlow を継承したクラスを作ります。便宜上ViewModelという名前を付けていましたが、公式のサンプルでは「〜DataFlow」という命名をしているようです。なお、AndroidDataFlowはAACの androidx.lifecycle.ViewModel を継承しているので、実装上は同じように扱うことができます。例えば、Hiltを用いたDIには @HiltViewModel を用いることができるということです。

import io.uniflow.android.AndroidDataFlow
import io.uniflow.core.flow.data.UIEvent
// 省略

class MainViewModel : AndroidDataFlow(
  defaultState = MainViewModelState.Initial,
) {
  // TODO
}

AndroidDataFlowを継承したクラス内では、action 内で setState を用いた状態の更新を、sendEvent を用いたOne Shot Eventの発火を行うことができます。Viewからアクションがトリガーされ、Stateの更新・Eventの発火処理が行われます。

fun onSomeAction() {
  action {
    setState(MainViewModelState.Loading)

    getSomeFlowUseCase()
      .map(/* map it here */)
      .onEach(::setState)
      .launchIn(viewModelScope)
  }
}

fun onAnotherAction() {
  action {
    sendEvent(MainViewModelEvent.SomeEvent)
  }
}

Stateについては io.uniflow.core.flow.data.UIState のサブクラスとします。sealed classなどでUIのStateをモデル化してあげると良さそうです。

import io.uniflow.core.flow.data.UIState

sealed class MainViewModelState : UIState() {
  object Initial : MainViewModelState()

  object Loading : MainViewModelState()

  data class ShowImage(val image: String) : MainViewModelState()

  object LoadFailed : MainViewModelState()
}

同様にEventについては io.uniflow.core.flow.data.UIEvent のサブクラスとします。

import io.uniflow.core.flow.data.UIEvent

sealed class MainViewModelEvent : UIEvent(){
  object SomeEvent : MainViewModelEvent()
}

View側では、LifecycleOwnerやFragmentに onStateonEvent が生えていますので、UIの更新は onState で、One Shot Eventに対する処理の実行は onEvent で行います。ここでいうStateやEventの実態はLiveDataです。Kotlin Coroutines Flowをサポートしようとした痕跡をソースコードから読み取りましたが、どうも頓挫したように思われます。

onState(viewModel) { state ->
  // TODO
}
onEvents(viewModel) { event ->
  // TODO
}

まとめ

Uniflowを用いた、MVI的なアーキテクチャを味見してみました。AndroidではAndroidDataFlowとそれが公開するStateとEventを用いることとなりますが、その実態はAACのViewModelとLiveDataでした。アーキテクチャとしては美しいですね。

ただ、ライブラリの更新が止まってしまっていることもありますので、ライブラリに頼らず、自分でUniflowのやっていることに相当するコードを書いて使ってもいいかな?とは思いました。ライブラリのソースコードもそんなに量はないです。

ライブラリのソースコードは読んでいて面白かったです🦄

#Android #MVI

書いている人 😎

profile

茨城県つくば市在住のモバイルアプリケーションアーキテクト(Androidが得意です)。モバイルアプリのアーキテクチャ、自動テスト、CI/CDに興味があります。いわゆる「レガシーコード」のリファクタリング・リアーキテクチャが好きです。

👉 もっと詳しく

著書 ✍

Android 依存性注入 ヒッチハイク・ガイド🧳

Androidアプリでの依存性注入(Dependency Injection)に入門するためのガイダンスです。依存性注入の概念やメリットを理解し、Dagger Hiltを用いてAndroidアプリに適用する方法を解説しています。

販売サイトへ🏃

ソフトウェアデザイン 2023年6月号📚

特集「クリーンアーキテクチャとは何か?」の第5章「モバイルアプリ開発における実践」を執筆しました。

販売サイトへ🏃

Android クリーンアーキテクチャ ヒッチハイク・ガイド🧳

Androidアプリでのクリーンアーキテクチャに入門するためのガイダンスです。クリーンアーキテクチャの概念を理解し、Androidアプリに適用する方法を解説しています。

販売サイトへ🏃

Android ユニットテスト ヒッチハイク・ガイド🧳

Androidアプリのユニットテストに入門するためのガイダンスです。初学者が混乱せずにAndroidアプリのユニットテストを書き始めることができる、ということを目的としています。

販売サイトへ🏃

Android MVVMアーキテクチャ入門🛠

Androidアプリ開発の初学者に向けた、MVVM(Model-View-ViewModel)アーキテクチャの入門書を書きました。初学者の方を確実にネクストレベルに引き上げる技術書です。NextPublishingより出版されています。

販売サイトへ🏃

関連記事 👀

お問い合わせ✉️

Androidアプリ開発、特にレガシープロジェクトに関するご相談はこちらまで📨

お名前

メールアドレス

お問い合わせ内容