蛇使いの日常

コーンスネークを飼っているPythonエンジニアの日常や技術のことなど

Android with kotlin - RepositoryはLiveDataを返すのではなくセットする役割で使った方がいいかも?

f:id:hebilist:20180210103423p:plain

こんにちは、Pythonエンジニアの蛇使いです。

今年からKotlinでAndroid開発を担当しています。毎日絶望!型あり言語をやってこなかったのにいきなりKotlinとか・・・。とは言うものの、ややこしいのはAndroidの部分ですね。

Architectureがいっぱいあってどれが良いのかわからなかったり、やり方がいっぱいあって悩みますね。私はMVVMにClean Architectureを取り入れた形になったと思います。

 

LiveDataを使う

やり方が色々あるので、公式?のAndroid Architecture Componentsを全て使うことにしました。そこでObserverFieldは一切使わず、全てLiveDataを使った方がシンプルになるので、Android Studioはプレビュー版で開発しています。Android Studioは3.1.6以降でないと、LiveDataでデータバインディングできないので。LiveDataを使えば、データバインディングもできて、ROOMもそのまま使えるのでシンプルです。

 

Repositoryの役目

本題ですが、RepositoryはService(Retrofit)からObservableを取得してsubscribeし、そのデータをRepository内で初期化したLiveDataにセットして、ViewModelに返す役目だとされてると思いますが、ViewModelで初期化したLiveDataを毎回Repositoryのメソッドに渡して、その渡されたLiveDataに対してRepositoryはsubscribeした結果をセットするようにした方がいいのではないかと思いました。

 

理由

  • ViewModelで初期化したLiveDataに、Repositoryで初期化しpostValueでセットしたLiveDataをそのまま代入すると、observeイベントが発動しない場合がある。

ActivityのonCreateでobserveしていて、データが変更された場合でも、ViewModelのLiveDataでpostValueしていないので、イベントが発動しない場合があります。

 

  • Repositoryには状態を保持しないほうが良さそう?

わざわざLiveDataをViewModelから渡さず、Repositoryで保持したものを使えば?とも思うかもしれないですが、Repositoryに状態を保持しておくと、破棄の管理を自分でしないといけないため、めんどくさそうです。ViewModelのプロパティなら、Activityが死んだ時に一緒に破棄してくれますね。

 

メジャーなやり方

RepositoryからLiveDataを返す場合は、ViewModel側でコンテナをnullで初期化しておいて、nullだったらRepositoryでデータを取得して代入しますが、初期化の時にLiveDataをセットしていないのでちゃんとイベントが発生します。これの何がいやかというと、Kotlinではプロパティやメソッドの呼び出し後に「?」をつけまくらないといけないことです。

nullableよりも、non-nullのほうが好きです。

とは言うものの、このやり方なら2回目以降はAPIを叩かず、ViewModelが保持しているLiveDataをすぐに返すので、こちらのほうがいいかもしれませんね。

しかし、POST後のResponseを監視したい場合は、やはりRepositoryでコンテナを保持しておかないといけないと思います。 

 

終わりに

久々に技術のことを書きましたが、コードを一切書いてない記事になりましたw

色々めんどくさいんですよ。色々・・・。

オーバーロード使えるとかは型あり言語良いんですけど、なんてったって今まで型なし言語でドカタしてきたので、お作法がキチキチだと苦痛です。まぁ慣れですかね。