guntamania

CoroutinesとLiveDataとKoin

[2020-08-16 Sun]

1年程度放置してしまった。 長らく副業案件していたが、久々にAndroidをキャッチアップしていのでメモ。

職場ではRxJavaばかりいじっているが、KotlinにはCoroutinesという対抗馬がいる。 色々なリポジトリ見ている限りまだRxJavaのほうが優勢なんだけど、そろそろCoroutinesも使い心地を確かめなければ。

ViewModelとKotlin Coroutinesの書き方あれこれ | stsnのブログ

ここのサイトが非常にうまくまとまっていた。 livedata builder というのがあるのか。。 これだと相当簡単にかけそうだが、汎用性にかけそうでもある。

あとはKotlinのKoinを使えばViewModelを簡単に注入できるのが感動した。

private val appModule = module {
    // ViewModel instance of MyViewModel
    // get() will resolve Repository instance
    viewModel { MainViewModel(get()) }
    factory { MainRepository(get())}
    factory { ApiClient() }
}

としておくと、

class MainFragment : Fragment() {
    private val mainViewModel : MainViewModel by viewModel()
    ...

これだけで注入できてしまう.. 今までだと Activity から obtainViewModel を実装して ViewModel をもらってくる必要があったが.. これは便利だ。

ただし、 LifeCycleOwner の注入は忘れないようにしよう

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    viewDataBinding.lifecycleOwner = this.viewLifecycleOwner
}

viewDataBindingを使っているのにこれを忘れていた.. 儀式的なものはあまり意味を考えないからついつい楽をすると忘れてしまうんだよね..

LiveData を更新したい

[2020-08-19 Wed]

LiveData Coroutine Builder 使ってUIを表示したい

単純に ViewModelなんかに書くと

val user = liveData<User> { runCatching { repository.getUser() } }

っていうコードになるんだけど、値を更新したいときに

viewmodel.user.observe(viewLifecycleOwner, .. )

とかって書いてみるんだけど動いてくれない..

で、以下の記事を参考にする。

LiveData 🤝 Coroutines

引用させていただく

private val _refresh = MutableLiveData<Unit>()
val data = _refresh.switchMap {
    liveData {
        emit(repository.getData())
    }
}
fun refresh() {
    _refresh.value = null
}

なるほど、購読対象を一個増やしてやるんだな..

だけどもどうもこの方法はアドホックな感じがある。 普通に liveData{ .. } がMutableLiveDataを返してくれればいいんだけど..

ところで、この liveData{ .. } という拡張が非常にググりずらいし、Githubも検索しづらい。 単にボタンUIで値を更新したいとかなのに、それでこんなアドホックな方法使わないといけないとしたら、ちょっときついかもしれない。