Sansan Tech Blog

Sansanのものづくりを支えるメンバーの技術やデザイン、プロダクトマネジメントの情報を発信

SansanのAndroid View→Jetpack Composeへの移行計画

はじめに

こんにちは!技術本部 Sansan Engineering Unit Mobile Applicationグループの石田です(@maxfie1d)。

2025年4月にSansanに入社し、現在はSansanのAndroidアーキテクトとしてモバイルアプリの開発に携わっています。

Mobileチームでは「技術負債返済」をテーマとしたTech Blogリレー企画を実施しています。本記事はその一環として、Android ViewからJetpack Composeへの移行計画についてご紹介します。

背景

SansanのAndroidアプリは約10年の歴史を持つアプリケーションです。 長年にわたって機能拡張を続けてきた結果、UI実装においてAndroid ViewとJetpack Composeの両方が混在した状態になっています。

現状、既存の画面の多くはAndroid ViewとXMLレイアウトで実装されており、一方で新規開発される画面ではJetpack Composeを採用しています。

既存のAndroid Viewで実装された画面をそのまま放置するのではなく、Jetpack Composeへの移行を進めていく必要があると考えています。 Jetpack Composeは宣言的UIのフレームワークとして、開発体験やメンテナンス性の観点から優位性があり、将来的な開発速度の向上や新技術への対応コスト削減につながると考えているためです(Compose を導入する理由  |  Jetpack Compose  |  Android Developers)。

と、言うのは簡単ですがSansanのAndroidのアプリの場合は大きく2つの課題がありました。

  1. Jetpack Composeに適さないアーキテクチャで作られた画面の存在
  2. 膨大な数の画面をどう移行するか

課題1: Jetpack Composeに適さないアーキテクチャで作られた画面の存在

課題の背景

Sansan Androidアプリは歴史のあるアプリケーションであり、開発期間中に複数のアーキテクチャパターンが採用されてきました。 その結果、アプリ全体で複数のアーキテクチャが混在している状況です。

特に、MVP(Model-View-Presenter)アーキテクチャで実装された画面については、「状態」が明確に表現されていない状況が多く見られます。 MVPではPresenterがViewのメソッドを直接呼び出すことでUIを更新するため、またAndroid ViewはView側がUIの状態を持つことができてしまうためPresenterなどのレイヤで状態管理がされていないケースがあるのです。

Jetpack Composeは宣言的UIであり、状態に基づいてUIを描画する設計思想を持っています。 そのため、状態が明確に表現されていない既存の画面をComposeに移行するには単純にUIを置き換えるだけでは不十分で、状態管理の見直しが必要ということになります。

解決策: ViewCoordinatorの導入

この課題に対処するため、ViewCoordinatorというクラスを用いた設計を行いMVPで実装された2つの画面で実際に適用してフィジビリティを検証しました。 ViewCoordinatorは、MVPアーキテクチャを活かしながらComposeに対応するためのブリッジ層として機能します。具体的には、以下のような役割を担います。

  • UDF(Unidirectional Data Flow)の実現: PresenterからViewへの双方向の依存を、単方向データフローに変換する
  • PresenterとViewのブリッジ: MVPのPresenterが直接View(Activity)のメソッドを呼び出す代わりに、ViewCoordinatorのメソッドを呼び出す
  • 状態の定義と公開: 画面の状態をデータクラスとして明示的に定義し、StateFlowとして公開する
  • イベントの定義と公開: 画面遷移などのイベントをsealed classとして定義し、Flowとして公開する

このアプローチにより、既存のMVPアーキテクチャを大きく変更することなくCompose化できるようになりました。 アーキテクチャを完全に作り直す(例えばMVPからFluxへ移行する)場合と比較して、開発コストとデグレリスクを抑えながら移行を進められます。

正直なところ最初は「完全に作り直ししないとCompose化するのは難しいかも...」と思っていたのですが、ViewCoordinatorを導入することで解決できました。

課題2: 膨大な数の画面をどう移行するか

課題の背景

Sansan Androidアプリには数百という膨大な数の画面が存在します。 そのうち約75%の画面がAndroid Viewで実装されています。それらすべてを効率よくJetpack Composeに移行するにはどうしたらよいでしょうか。

解決策: AIがキーになる

この課題に対する答えはAIを活用し尽くすことです。

2025年時点の開発生産性を考慮してざっくり試算すると、すべての画面を移行するには 3年 かかる計算になります。とても時間がかかりますね。

とはいえ実際にはもっと早く移行が完了するのではと期待する部分もあります。 というのもAIモデルの進化は凄まじい速さで進んでいます。移行中の長いタイムスパンの中でより高性能なAIモデルが開発され移行作業のほとんどを行ってくれるかもしれません。

そしてもう1つ重要なのは、洗練されたプロンプトとコンテキストの充実 です。 どんなに素晴らしいAIであっても、「Jetpack Composeに移行して」と指示するだけで理想的なコードを出力してくれるわけではありません。

具体的には、以下のような情報をAIに読み込ませる必要があるでしょう。

  • Jetpack Composeのコーディングルール
  • 既存の実装例
  • ViewCoordinatorを使用したMVPの移行手順
  • Figmaのデザインデータ (デザインシステム、画面デザイン)

現時点では具体的な移行実績はまだ少ない段階ですが、今後のブログ記事で具体的な効果について紹介できればと思います。

まとめ

本記事では、SansanのAndroid ViewからJetpack Composeへの移行において直面した2つの課題と、それぞれの解決策について紹介しました。 技術負債返済には、寝て起きたら終わっているという都合のよい話はありませんが、適切な戦略とAI活用によって現実的な時間軸で達成できると考えています。 本記事が読者の皆さまのご参考になれば幸いです。

© Sansan, Inc.