Slide 1

Slide 1 text

STAGE 1 SESSION TAG Sansan Androidアプリの変遷と Jetpack Composeの導入 Android Engineer/Manager 山口 佳祐 Android Engineer 赤城 史哉 アーキテクチャ

Slide 2

Slide 2 text

技術本部 Mobile Applicationグループ Androidエンジニア 前職ではAndroidアプリの受託開発に従事。2019年にSansan入社後、 Sansan Android アプリの開発・運用を担当。 赤城 史哉

Slide 3

Slide 3 text

このセッションの概要

Slide 4

Slide 4 text

• Sansan Android アプリの変遷 • SansanとAndroidアプリについて • アーキテクチャの変遷 • ライブラリの変遷 • Jetpack Compose導入について • Jetpack Composeとは • Jetpack Compose導入の理由 • Jetpack Compose導入の進め方 概要

Slide 5

Slide 5 text

SansanとAndroidアプリについて

Slide 6

Slide 6 text

• 法人向けクラウド名刺管理サービス • 当社の営業を通じて法人ユーザーと利用契約を結ぶ • サブスクリプション型ビジネスモデル • 利用料をお支払いいただくことで利用できる • 新規契約数を増やすこと、解約数を減らす(出来るだけ長期でご利用いただく) ことが重要 SansanとAndroidアプリについて Sansan事業のビジネスモデル

Slide 7

Slide 7 text

• 名刺管理 • スマホのカメラを使って名刺登録 • 登録した名刺に関連する企業のニュースを確認 • 商談メモや議事録 (コンタクト機能) • 社内チャット SansanとAndroidアプリについて アプリの主な機能

Slide 8

Slide 8 text

• ユーザーが必要とする機能を追加する • 競合他社より機能面や契約面で優位である • ユーザーの課題にフィットするような使い方を提案できる • 既存顧客の顧客満足度を上げる • 口コミ効果が期待できる SansanとAndroidアプリについて 「新規契約数を増やす」ために

Slide 9

Slide 9 text

• 利用率を向上させる • 使われなければ投資効果がない(とユーザーが思う) • 導入効果を最大化する支援(カスタマーサクセス) • 顧客満足度を上げる • 機能の信頼性向上 (バグを減らす) • ユーザーが必要とする機能を追加する SansanとAndroidアプリについて 「解約数を減らす」ために

Slide 10

Slide 10 text

• 速いペース、並列での機能開発 • リリースを増やす • より高い品質。信頼性の確保 →それらに耐えうるアーキテクチャ SansanとAndroidアプリについて 開発体制に求められるもの

Slide 11

Slide 11 text

アーキテクチャの変遷

Slide 12

Slide 12 text

• 初期 • MVVM + Repositoryパターン • リニューアル (2017) • Kotlin化, MVP + Clean Architecture(一部MVVM) • アーキテクチャ刷新(2019) • Flux + Clean Architecture • マルチモジュール化 アーキテクチャの変遷 アーキテクチャの変遷

Slide 13

Slide 13 text

• コード行数:約15万行 • モジュール数:約70モジュール アーキテクチャの変遷 現在のAndroid アプリの規模

Slide 14

Slide 14 text

• 初期 • MVVM + Repositoryパターン • リニューアル (2017) • Kotlin化, MVP + Clean Architecture(一部MVVM) • アーキテクチャ刷新(2019) • Flux + Clean Architecture • マルチモジュール化 アーキテクチャの変遷

Slide 15

Slide 15 text

• コードの書きづらさ。 • 状態の管理場所が実装者に依存 • Activity, Fragmentで状態を持つ or Presenterで持つ etc… • PresenterとUseCaseの責務が曖昧 • 可読性の悪さ • ViewとPresenterを行き来 • コンフリクトの多さ • Fat PresenterかつUseCaseの粒度が大きい • 多人数で同時に変更してコンフリクトしやすい • 並列開発における速度と品質の低下 アーキテクチャの変遷 MVPの課題点

Slide 16

Slide 16 text

Facebookが提唱したアーキテクチャ データフローを単方向に限定。複雑な状態遷移でも管理しやすい アーキテクチャの変遷 Fluxとは 出典:https://facebook.github.io/flux/docs/in-depth-overview/

Slide 17

Slide 17 text

広義の意味でのMVVM ViewModelの役割を各クラスに分割、それぞれのクラスの責務を単一に アーキテクチャの変遷 Sansan AndroidにおけるFlux 出典:https://developer.android.com/jetpack/guide

Slide 18

Slide 18 text

• コードの書きづらさ。 • 状態の管理場所が実装者に依存 > Activity, Fragmentで状態を持つ or Presenterで持つ etc… • PresenterとUseCaseの責務が曖昧 →各クラスの責務が明確に。迷わず書ける アーキテクチャの変遷 Fluxで目指したMVPの課題解決

Slide 19

Slide 19 text

• 可読性の悪さ • ViewとPresenterを行き来 →単方向のデータフローのため、データの流れを追いやすい アーキテクチャの変遷 Fluxで目指したMVPの課題解決

Slide 20

Slide 20 text

• コンフリクトの多さ • Fat PresenterかつUseCaseの粒度が大きい →責務が単一のクラス群。特定のクラスがFat化しづらい • 多人数で同時に変更してコンフリクトしやすい →同じファイルをいじる事がほとんど無くなる アーキテクチャの変遷 Fluxで目指したMVPの課題解決

Slide 21

Slide 21 text

• アプリがデータの表示に集中できる • ViewはStoreのデータをそのままバインドすればよいだけ • チームメンバーがアーキテクチャを好きになれる • 開発者も人間。モダンな方がモチベーションが上がる アーキテクチャの変遷 その他のFluxの利点

Slide 22

Slide 22 text

• MVPの問題は解決出来た • 開発を加速できている • コンフリクトのしづらさ • レイヤ・クラス毎の役割の明確化 • 比較的シンプル。新しくジョインした人もすぐキャッチアップ可能 • もちろん銀の弾丸ではなく、細かな問題点もあった • 特定のライブラリとの相性の悪さ等 アーキテクチャの変遷 2年間Flux化を進めてみて

Slide 23

Slide 23 text

• 複数のステップを計画して実施 • 開発する際のビルドスピードが約半分に改善 • 依存関係を強制する。レイヤーを超えてクラスを参照できないように アーキテクチャの変遷 マルチモジュール化

Slide 24

Slide 24 text

採用ライブラリの変遷

Slide 25

Slide 25 text

• Jetpack • Lifecycle, ViewModel, WorkManager etc… • Dagger • RxJava, Coroutine • Epoxy • Glide 採用ライブラリの変遷 現在採用しているライブラリ(一部)

Slide 26

Slide 26 text

• Airbnb製 • RecyclerViewで複雑な画面を構成するためのライブラリ • サブヘッダーの表示、複数の異なるレイアウトが混在するリストの表示に便利 • 使い方もそこまで難しくない • Composeをしばらく導入できそうにない場合は検討の余地あり 採用ライブラリの変遷 Epoxy

Slide 27

Slide 27 text

• Jetpack • バックグラウンド処理を行うためのライブラリ • ドキュメントが充実している。実装がそこまで難しくない • ネットワーク接続が確認出来たら実行などの条件付が簡単 • OSバージョンごとの挙動の差分に簡単に対応 採用ライブラリの変遷 WorkManager

Slide 28

Slide 28 text

• Jsonパーサーライブラリ • GsonではNullの扱いに問題があり、乗り換えた • Kotlin Serializationも検討したが、下記の理由で不採用に • Stableになってからそこまで時間が経っていなかった • Sansan AndroidアプリでのJsonアダプターの用途にIFがマッチしていなかった 採用ライブラリの変遷 Gson -> Moshi への置き換え

Slide 29

Slide 29 text

• 初期は直接話して都度決めていった • 人数が増えたことに伴い、交通整理が必要に • 選定基準を明文化して、Androidチームのリーダーが承認する形に • 選定基準の例 • 開発の活発度(最終コミットがいつか) • 学習コスト、ドキュメント • 安定版であるか否か etc... 採用ライブラリの変遷 ライブラリ選定について

Slide 30

Slide 30 text

技術本部 Mobile Applicationグループ アシスタントグループマネジャー 新卒で外資系のセキュリティ会社に入社し、それ以降Androidアプリの開発に 従事。2018年にSansanに入社し、Androidアプリの開発を担当。 リードエンジニアを経て直近はアシスタントグループマネージャとして Androidチームのアーキテクトとマネジメントを担当。自身も開発を行う。 山口 佳祐

Slide 31

Slide 31 text

Jetpack Composeとは

Slide 32

Slide 32 text

• 2021年7月に1.0がリリースされたネイティブ UI をビルドするための Android の 最新ツールキット • Googleによって開発 • 従来のXMLによるレイアウトではなく、Kotlinによるレイアウト • UIを命令的に更新するのではなく、宣言的に作られた状態をUIに反映する Jetpack Composeとは

Slide 33

Slide 33 text

Jetpack Composeとは 出典:https://developer.android.com/jetpack/compose?hl=ja

Slide 34

Slide 34 text

Jetpack Compose導入の理由

Slide 35

Slide 35 text

• 開発速度を向上させ、リリースを増やしたい • 複雑な状態を持つ画面の可読性の向上 • リスト表示の改善 • 成長機会 Jetpack Compose導入の理由

Slide 36

Slide 36 text

複雑なデザインや状態を持つレイアウトではXMLが複数に分かれている。 状態に応じてViewを切り替えているが全ての切り替えをDataBindingやKotlin側で行うのは大変で 可読性が低い。状態の切り替え忘れなどバグの原因になる。 Jetpack Compose導入の理由 複雑な状態を持つ画面の可読性の向上 Activity activity.xml include include View1 Store included_ layout1.xml included_ layout2.xml ・ ・ Recycler View item1.xml item2.xml ・・・

Slide 37

Slide 37 text

複雑なデザインや状態を持つレイアウトではXMLが複数に分かれている。状態に応じてViewを切り替え ているが全ての切り替えをDataBindingやKotlin側で行うのは大変で可読性が低い。状態の切り替え忘れ などバグの原因になる。 => Jetpack Composeの導入により同一Kotlinファイル内でレイアウトを扱える。上位のComposable に状態を渡して下位のComposableに下ろしていくことで状態を簡潔に切り替えられる Jetpack Compose導入の理由 複雑な状態を持つ画面の可読性の向上 Activity Store Composable

Slide 38

Slide 38 text

• Epoxyに課題感 • idの生成に注意が必要。重複するとクラッシュする > 重複がないと思いidに設定したパラメータに実は重複があり後にクラッシュに • コード生成による実装のため実装が追いにくい > ブランチを切り替えているとコードジャンプが行えなくなることが多々 • クセがある Jetpack Compose導入の理由 リスト表示の改善

Slide 39

Slide 39 text

• まだベストプラクティスが定まっておらず自分たちで解決していくチャンス • 新たな技術に触れるチャンス Jetpack Compose導入の理由 成長機会

Slide 40

Slide 40 text

Jetpack Compose導入の進め方

Slide 41

Slide 41 text

• チームでの導入の意思決定 • 方針を定める • 技術研鑽タイムでキャッチアップ • 環境設定 • 各開発で導入。トライ&エラーで改善 Jetpack Compose導入の進め方

Slide 42

Slide 42 text

• チームとして取り組んでいくぞという宣言と合意 Jetpack Compose導入の進め方 チームでの導入の意思決定

Slide 43

Slide 43 text

• 導入に向けての不明点・議論ポイントをあげる • 不明点の調査、各議論ポイントの主担当を決めて推進する • 議論ポイントの結論を決め、方針を定める Jetpack Compose導入の進め方 方針を定める

Slide 44

Slide 44 text

• 既にStoreが画面の全状態を持つ設計になっているため大きな変更点はなし • 最上位のComposableがStoreの状態をobserveAsStateとして受け取って下位に 渡していく Jetpack Compose導入の進め方 方針1: 現状のFluxにどう組み込むか Dispatcher Store Action Creator Activity Composable

Slide 45

Slide 45 text

• Atomic Designをベースに検討中 • 既存のViewの画面を参考に最初のルール作り • Reactなど他プラットフォームなどの事例も参考に Jetpack Compose導入の進め方 方針2: Composableの粒度をどうするか

Slide 46

Slide 46 text

• 17:50からのLTにて • テックブログ https://buildersbox.corp-sansan.com/entry/2021/09/16/110000 Jetpack Compose導入の進め方 技術研鑽タイムでキャッチアップ

Slide 47

Slide 47 text

• 開発環境アップデート • compose 1.0.2から依存しているバージョンへアップデート > Kotlin 1.5.21 > Kotlin Coroutines 1.5.0 > activity-ktx 1.3.1 > lifecycle 2.3.0 • Theme/Typographyの設定を行う Jetpack Compose導入の進め方 環境設定

Slide 48

Slide 48 text

• 絶賛導入開始中 • 最初から完璧な設計や運用はできない。 導入していく中でフィードバックを拾っていき改善につなげる Jetpack Compose導入の進め方 各開発で導入。トライ&エラーで改善

Slide 49

Slide 49 text

現状の課題感

Slide 50

Slide 50 text

sticky header が Experimental Pagingライブラリを使わない ページングのベストプラクティス 現状の課題感

Slide 51

Slide 51 text

まとめ

Slide 52

Slide 52 text

• SansanではJetpack Composeを導入開始中 • 導入は開発速度を向上させ、 リリースを増やすことと成長機会を得るため • 導入にあたってチームで議論点をあげ方針を検討 • 並行してキャッチアップと環境設定を進める • トライ&エラーでフィードバックを拾っていき改善につなげる • sticky headerやページングなど課題感あり まとめ

Slide 53

Slide 53 text

Twitter @phicdy Android Engineer/Manager 山口 佳祐 Android Engineer 赤城 史哉 Twitter @ginyolith_tech