inSmartBank

B/43を運営するSmartBank社のメンバーによるブログです

「B/43」のAndroidアプリをリリースしました!使用している技術を紹介します。

こんにちは。

「B/43」のAndroidアプリ開発に携わっている あんざいゆき(yanzm) です。

先日「B/43」のAndroidアプリをリリースしました🎉🎉

play.google.com

この記事では「B/43」のAndroidアプリで採用している技術や苦労した点、工夫した点などを紹介します。

採用している技術(抜粋)

Jetpack Compose

一番の特徴は Full Jetpack Compose にした点です。 開発のお話をいただいた今年の春時点で Jetpack Compose は beta 版がリリースされており、夏には stable 版がリリースされることも発表されていました。 今から開発するなら Jetpack Compose でやりたいと思っていたところ、iOS / Android エンジニアをしている nakamuuu からも Jetpack Compose でという話があり、即これでいこうと決まりました。

Full Jetpack Compose で作る場合、次に決めないといけないのが画面遷移をどうするかです。 「B/43」アプリでは SingleActivity にして画面遷移も Jetpack Compose で管理することにしました。そのために Compose で画面遷移を行うためのライブラリである Navigation Compose を採用しています。 公式のサンプルコードで SingleActivity 構成のものは全て Navigation Compose を使っており、これらも参考にしました。

Navigation Compose は画面遷移による Back Stack を管理してくれます。例えば画面Aから画面Bに遷移すると、Back Stack は画面Aの上に画面Bが積まれた状態になります。この状態でバックキーを押すと画面Aに戻り、Back Stack は画面Aだけが積まれた状態になります。

また Navigation Compose では、Back Stack に積まれている間をライフサイクルとする ViewModel を作ることができます。つまり、画面のライフサイクルと同じライフサイクルの ViewModel を用意することができるということです。これにより、画面ごとに ViewModel を用意してその画面に関する処理を持たせる、という構成にすることができました。

f:id:yanzm:20211215192714p:plain

AndroidX 以外の Compose 関係のライブラリとしては、Jetpack Composeの便利ライブラリ集である Accompanist、画像読み込みライブラリの Coil compose、LottieをComposeで使うための Lottie compose を使っています。

Dagger Hilt

Dependency Injection ライブラリは Dagger Hilt を採用しています。 もともと Dagger や Hilt の経験があったこと、Hilt と Jetpack Compose を組み合わせて使うための仕組みが用意されていることが選んだ理由です。 Composable 内で ViewModel を取得するための関数が Hilt に対応していたり、Navigation Compose と Hilt を組み合わせる方法が用意されているので、簡単に組み込むことができました。

Coroutines

非同期処理は Kotlin coroutines を使っています。Jetpack Compose も coroutines を使っているので、他を使う理由はないかなと思います。

Jetpack Compose で苦労した点

ライブラリの不安定さ

一番バグに困らされたライブラリは Navigation Compose です。特に画面遷移時のアニメーション機能が入ったときに Nested Navigation 周りがクラッシュするようになってしまい、しばらくライブラリのバージョンを上げられませんでした。

Accompanist は更新頻度が高く、挙動が変わったりバグが入ったりすることがままありました(バグが修正されるのも早いです)。

Compose 自体は 1.0 の stable 版がリリースされていますが、周辺のライブラリは最初の stable 版がリリースされていないものもあり、まだまだこれからという感じです。

機能の不足

Compose 本体もまだまだ機能が足りていません。たとえば TextView には auto size 機能がありますが Compose にはまだありません。文字入力周りも不安定です。文字入力関係では何ヶ月も解消されずにいる issue が残っていますし、特にマルチバイト文字入力では文字数制限機能や入力文字の種類を制限する機能がうまく動きません。 そのため文字数制限は金額など数字入力にだけ行い、それ以外の文字入力については文字数制限はせず送信ボタンが押されたときにチェックするようにしています。

工夫した点

Hilt の Custom Component による Scope管理

「B/43」アプリでは個人口座の他にペア口座を持つことができ、アプリで今表示している口座を切り替えることができます。これはSNSアプリでのアカウント切り替え機能のようなものです。 口座ごとにカード情報も履歴情報も異なり、口座が切り替わった際には以前の口座に紐づく情報を持った ViewModel や Repository などのインスタンスを破棄する必要があります。

「B/43」アプリではこれを実現するために、Hilt の Custom Component 機能を使って、口座に紐づく Scope の Custom Component を用意しています。 口座が切り替わった際は、この Custom Component を作り直したのち Activity を作り直しています。これにより ViewModel が依存する Repository のうち、口座に紐づく Scope の Repository は新しい口座の情報で作り直され、Singleton Scope の Repository は維持されるという挙動が実現できます。

f:id:yanzm:20211215192818p:plain

f:id:yanzm:20211215192822p:plain

グラフとスクロールの同期

私が作成したUIで一番大変だったのがトップ画面のグラフとその下に表示されるタイムラインリストのスクロール同期です。 グラフのハンドルをドラッグするとタイムラインリストが該当のところまで自動でスクロールします。一方、タイムラインリストをスクロールした場合もグラフのハンドルが該当のところまで移動します。さらにグラフは横方向にページングされていて、スワイプすることでハンドルの位置が変わり、タイムラインリストがスクロールします。 この双方向の同期を処理するのが大変でした。 ぜひ実際のUIを触ってみてもらえたらと思います。

f:id:yanzm:20211216100552g:plain

最後に

「B/43」の Android アプリがリリースできてとても嬉しいです。多くの方に使っていただけるようこれからも頑張ります。

Full Jetpack Compose での開発はとても楽しいです。UI部分だけでなく画面遷移や状態管理、データの持ち方などまだまだ試行錯誤中です。

新しい技術をいろいろ取り入れていますが、アプリは安定して動作することがユーザーにとって最も重要だと考えています。 一方スタートアップにとっては開発スピードも重要です。安定性とスピード、この両方を維持するために変更を容易かつ安全にできるアプリの設計をこれからも模索していきたいと思います。


スマートバンクでは一緒に B/43 を作り上げていくメンバーを募集しています!カジュアル面談も受け付けていますので、お気軽にご応募ください 🙌

smartbank.co.jp