JetpackでもRoom, Paging 3, DataStore等様々なライブラリがkotlin coroutines flowを使い始め、もはやAndroid開発にはflowが必要不可欠になってきました。
そんな中、以前紹介したStateFlowに加えて、SharedFlowが1.4.0-M1から登場しました。
少し複雑に感じますが、実はかなり整理されており、以前より使いやすくなっていると思っています。
今回は、Flow、SharedFlow、StateFlowの概要に関して紹介し、各々の詳細に関しては別途まとめたいと思います。
Androidで開発する際、文字列のリソースは res/values/strings.xml に書いて管理すると思います。
それらを実際に文字列として取得するためには、contextが必要になります。
一方で、ViewModelにActivity contextを渡すことはメモリリークの危険性があるため、アンチパターンとされています。
Application contextで文字列を取得する方法もあると思いますが、言語切替時に正しくUIが更新されない等、あまり良くないと感じました。
ViewModelではenum等を作成し、View側で文字列に変換する等の方法もあると思いますが、細かい文字列の制御が難しくなります。
今回はActivity contextを使いつつ、いい感じにString resourcesを扱う方法について紹介したいと思います。
Androidの複雑なlifecycleに対応するのに、jetpackのLifecycleObserver等の仕組みは非常に強力です。
LifecycleObserverにはいくつか種類がありますが、LifecycleObserverのinterfaceにOnLifecycleEventのアノテーションを付けてやる方法が一番一般的だと思っていました。
しかし、java 8環境下ではDefaultLifecycleObserverのほうが強く推奨されていたので、その説明と、移行に関する注意点をまとめてみます。
Navigation Componentの登場により、画面遷移をFragmentベースで行う例が増えてきたように思います。
Fragmentで画面遷移をさせることで、toolbarやbottom navigation view等の共通のUIを表示し続けられるようになったり、activityでの画面遷移よりパフォーマンスがよかったり、いくつかの利点があります。
一方で、activityでの画面遷移とは違い、navigation利用時は遷移時にデフォルトのアニメーションがつきません。
そこで、今回はいくつかの遷移アニメーションの例を提示したいと思います。
StateFlowもリリースされ、kotlin coroutines flowがますます存在感を増してきています。
一方、単体テスト等を書こうとした際、こういったストリームをテストするのは比較的難しいです。
今回は、僕が普段実際に使ってるテスト用utilとその使い方について紹介したいと思います。
Kotlin Android Extensionは現在2つ機能があり、findViewByIdを省略できるviewsとParcelableの実装を楽にしてくれるparcelizeがあります。
特に viewsは非常に便利で、僕自身もよく使っていました。
一方、ViewBindingというものも登場し、DataBindingの軽量版みたいな立ち位置で、こちらもfindViewByIdを省略することができます。
Kotlin Android ExtensionとViewBinding、DataBindingを比較し、使い分けについて議論したいと思います。
Androidに置いてアクセシビリティの観点からボタンのサイズは縦横共に最小48dpを推奨されています。(iOSは44pxみたいです)
また、デザイン上そのサイズに満たない場合でも、その周りもタッチできることが求められています。
今回はそれの具体的な実装方法について紹介したいと思います。
fragmentが難しい理由の一つとして、viewの生存期間よりfragmentの生存期間のほうが長い、というところがあると思います。
そのため、viewが再生成された際に正しく新しいviewを参照できなかったり、viewへの参照が切られずメモリリークしたりということがよく起きます。
今回はviewへの参照をby lazyの形で安全に書ける仕組みを考えてみたいと思います。
以前、kotlin coroutines flowを使って、LiveDataを使わずMVVMを行う方法について書きました。
その後、StateFlowも登場し、ますますLiveDataの代わりに、kotlin coroutinesを使う手法が確立してきたように感じます。
Flowをactivityやfragmentで安全にcollectするためには、lifecycle scopeを使う必要があります。
しかし、lifecycle scopeは通常のcoroutines scopeにいくつかメソッドが追加されており、少し複雑です。
今回はflowをlifecycleScopeで安全に使う方法について考えます。
androidアプリでは、activityの背景を透明にすることで、dialogのように扱ったり、様々なUI表現をすることができます。
最近はFragment周りの環境が整ってきた影響であまり使われなくなってきた印象がありますが、まだまだ使っているプロジェクトもあるのではないかと思います。
透明activityを使った場合、実はactivityのlifecycleが通常とは異なる動作をしており、少し詰まったのでまとめます。
kotlin coroutines 1.3.6にて、StateFlowというものが導入されました。
状態管理のために用いられる型で、将来的にConflatedBroadcastChannelから置き換わるとも言われています。
今回は、ドキュメントを詳しく見つつ、実際にコードを動かして特徴について見ていきたいと思います。
サーバ間、サーバとクライアント間の通信でgRPCを採用することは、様々なメリットがあります。
AndroidでもgRPCの採用事例が増えてきたように思います。
以前はgrpc/grpc-javaを使ってstubを生成してたと思うのですが、いつの間にかgrpc/grpc-kotlinも出ていました。
しっかりとkotlin coroutinesをサポートしており、かなり便利だったので、導入方法を紹介します。
LiveDataは非常に便利ですが、以前も書いたとおり、hotとcoldがわかりにくい、内部がjavaのためnon nullを扱いにくい等、ところどころ不自由な点があります。
また、kotlin coroutines flowを採用している場合、どこまでflowで流して、どこでLiveDataに変換するか、という問題に直面します。
なら、いっそのことLiveDataを使わず、全てflowでMVVMを完結させられるのではないかと思い、今回試してみました。
その際に気をつけた点、気がついたこと等をまとめます。
最近のandroid開発において、複雑なlifecycleに対応するのにLiveDataは重要な役割を果たすことが多いです。
その他のstream系ライブラリと比べても非常にシンプルで、初心者でも比較的親しみやすいと思います。
一方で、意外なところで躓くことも多いのが実情かと思います。(経験談)
今回はHot, Coldの話を主軸に、LiveDataの躓きやすいポイントについて触れたいと思います。