Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
マルチモジュールアプリの画面遷移処理実装
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
こやまカニ大好き
October 28, 2022
Programming
6.8k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
マルチモジュールアプリの画面遷移処理実装
After Party DroidKaigi 2022 で発表したスライドです。
https://cookpad.connpass.com/event/260672/
こやまカニ大好き
October 28, 2022
More Decks by こやまカニ大好き
See All by こやまカニ大好き
Androidアプリの One Experience リリース
nein37
0
5.6k
クックパッド Android アプリのマルチモジュール化とデモアプリの活用
nein37
1
7.1k
2020年代の WebView 実装 / saikou_no_webview_2021
nein37
2
12k
Androidアプリをいつまでも楽しく開発し続けるための取り組み
nein37
5
2.7k
minSdkVersion=21にしてから1年経った話
nein37
8
2.5k
Androidアプリエンジニアの基礎知識
nein37
16
11k
クックパッドアプリのマルチモジュール化への取り組み
nein37
11
11k
Android のセキュリティよくなってきた話
nein37
3
2.6k
Androidアプリのデザイン整理への取り組み
nein37
1
1.1k
Other Decks in Programming
See All in Programming
Performance Optimization With LLMs
xleitix
0
150
Kotlinの15年とServer-Side Kotlin
n_takehata
1
150
IBM Bob Dojo #1 仕様駆動開発入門
oniak3ibm
PRO
0
400
パスワード再設定メールのURLについて知っておこう
uyuki234
0
160
パズルゲームの作り方 / how to make puzzle games
kaityo256
PRO
2
300
GemmaをJevのように使ってみる / Use Gemma like Jev
kishida
5
800
個人開発者よ、Honoを使え(おじさんver)
tanahiro2010
2
260
AIで開発が速くなった先で、開発チームは何を目指すか
shihochan
1
1.6k
TechTown - Creating Composable Callables in Contemporary C++
rollbear
0
130
C#の現在地 進化の歴史と、AI時代の.NET Everywhere
neuecc
5
5.2k
ActionController meets Protocol Buffers
sorah
0
560
Long Living Tokens, Die, Die, Die! (or: The One Ring is Banned in Modern)
sylph01
0
320
Featured
See All Featured
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3.1k
Practical Orchestrator
shlominoach
192
12k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.4k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.3k
Building Better People: How to give real-time feedback that sticks.
wjessup
371
20k
A Soul's Torment
seathinner
8
3.8k
Being A Developer After 40
akosma
92
590k
It's Worth the Effort
3n
188
29k
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
1
450
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
640
Transcript
マルチモジュールアプリの画 面遷移処理実装 こやまカニ大好き
自己紹介 こやまカニ大好き レシピサービス開発部 所属 モバイルアプリ開発の生産性を向上させ るタスクに従事 去年から WebView 大好き
今日のトピック • クックパッドアプリの構成 • クックパッドアプリの画面遷移実装 • まとめ
クックパッドアプリの構成
クックパッドアプリの構成 • マルチモジュールプロジェクト ◦ 画面実装は View(Compose)と関連ロジックを Scene という単位で定義 ◦ 関連のある複数
Scene で機能モジュール(feature module) を構成 ◦ 共通ロジックやドメイン層は役割ごとにライブラリモジュール (library module)を構成 • モジュール数は全体で 52 ◦ 機能モジュール 21 ◦ ライブラリモジュール 19 ◦ そのほかは App モジュールや Demo モジュール
モジュール構成
画面遷移の実装 • クックパッドアプリでは現在 Navigation Component 未使用 • 今回お話するのは全て自作している画面遷移実装の話 • Navigation
Component 未使用の理由は主にタイミングの問題 ◦ Navigation Component 登場時点でマルチモジュール化していたため、導入が難しかった ◦ クックパッドアプリの画面遷移が複雑で利用できる箇所が限られていた ◦ 特にボトムタブに Multiple Back Stacks 相当の実装を自前で入れていたので乗り換えが難し い状況だった
クックパッドアプリの 画面遷移実装
モジュール間画面遷移の基本 • 機能モジュールAは機能モジュールBを直接参照しない ◦ もし参照しようとすると画面によってはモジュール同士の循環参照になってしまう • 別モジュールの画面を生成するため、 navigation module に
Factory を定義す る • 各画面は navigation module の Factory を経由して画面を生成し、遷移処理を 実装する
モジュール間画面遷移の基本 FeatureA SceneA FeatureB SceneB :FeatureA:SceneA と :FeatureB:SceneB は相互に画面 遷移したい
お互いが見える状態にしようとする と :FeatureA と :FeatureB の循環 参照になってしまう
モジュール間画面遷移の基本 FeatureA SceneA FeatureB SceneB Navigation DestinationFactory fun createSceneB() fun
createSceneA() Navigation モジュールの DestinationFactory という interface を経由することにより、モジュール の循環参照を防ぐ
モジュール間画面遷移の基本 FeatureA SceneA FeatureB SceneB Navigation DestinationFactory fun createSceneB() Application
DestinationFactoryImpl fun createSceneB() 実装 Application モジュールに DestinationFactory の実態があり、 各Sceneのインスタンスを生成する Application モジュールは全てのモ ジュールを参照しているので全ての 画面のインスタンスを生成可能
追加要求1 ボトムタブごとに画面遷移の履歴(Back Stacks) を切り替えられるようにしたい
Back Stacks の切り替え • ボトムタブを切り替えた際、タブごとに Back Stacks を保存して切り替える機能 ◦ いわゆる
Multiple Back Stacks 相当の機能 • PrimaryNavigationFragment という仕組みを使い、タブごとに FragmentManager を制御する Fragment を切り替えることで実現している ◦ Activity と実際に表示する画面の間に Fragment 階層を一枚挟み、タブ切り替えを 上位 Fragment の切り替えでやっているイメージ ◦ back の挙動なども自動的に切り替えてくれる ◦ 現在は FragmentManager に saveBackStack/restoreBackStack があるのでもう少しわかり や すい仕組みで切り替え可能
Back Stacks の切り替え • requireActivity().supportFragmentManager を使う代わりに以下のような方法 で FragmentManager を取り出すことで常にタブ挙動を考慮した画面遷移にで きる
NavigationController の導入 • 毎回 の記述を書いていられないので、 NavigationController という仕組みを導入した • アプリ内の画面遷移における共通処理を吸収するレイヤー ◦
処理対象の FragmentManager の選択 ◦ replace 時の containerViewId 指定 ◦ backstack の管理
NavigationController のコード(一部)
NavigationController の生成
NavigationController を使った画面遷移
追加要求2 条件によって遷移先が Fragment だったり Activity だったりする画面遷移を実装したい
遷移先がActivity/Fragmentで分岐 • ユーザー状態などによって遷移先が変わるアクションが存在する • ログイン済みの場合は目的の画面(Fragment)、未ログインの場合はログイン画 面(Activity)という複雑なパターンも存在する
Destination の導入 • Destination は遷移先(Fragment, DialogFragment, Intent)をラップする sealed class •
NavigationController が Destination への遷移をサポートすることで画面実装 では遷移先が Fragment 、 DialogFragment 、 Intent のいずれであるのか考 慮する必要がなくなった ◦ Result を受け取るケースでは考慮する必要があるので Destination を使わない処理になって いる
Destination の実装
NavigationController 側の処理
追加要求3 URLによる画面遷移処理を実装したい
URL による画面遷移処理 • いわゆるディープリンク処理 • 遷移先は Fragment だったり Activity だったり
• 外部からのアプリ起動、WebView内での遷移、APIレスポンスからのアクション など様々な箇所で同じ挙動を実現したい
DestinationParams の導入 • DestinaionParams は Destination を生成するための情報をまとめたもの • URLから遷移先(Destination)の種別と必要なパラメータを抽出し、プロパティと して保持する
• DestinationParams の定義は sealed interface なため、when による分岐処理 でパターン網羅しやすい
DestinationParams の実装
DestinationParams の利用 ほとんどのケースで、以下のような実装だけで動作するようにしている
WebView における DestinationParams • 去年の DroidKaigi で発表した時点では DestinationParams は存在していな かった
• 現在は WebView 内のURL解釈も DestinationParams で共通化しているため、 WebView画面で実装すべきメソッドは DestinationParams を渡して遷移するメ ソッドだけになった
WebView における DestinationParams
DestinationParams の機能ごとのタグづけ 各 DestinationParams がサポートする機能ごとにタグづけを行なっている sealed interface は複数実装できるので、サポートする機能によって DestinationParams の
sub interface をそれぞれ実装している 例えば、ディープリンク関連の処理では DeepLinkSupportedDestinationParams だ けを用いることで、 when 分岐の無駄な記述を減らすことができる
DestinationParams の機能ごとのタグづけ
まとめ
クックパッドアプリの 画面遷移を支える自作コンポーネント • DestinationParams ◦ 遷移先と必要なパラメータをまとめた sealed interface ◦ (理想的には)画面の数だけ
DestinationParams が存在する • Destination ◦ 画面遷移に必要なFragmentやActivity(Intent) などの実態を抽象化する sealed class ◦ (基本的には) Factory を経由して DestinationParams から生成される • NavigationController ◦ Destination による画面遷移をサポートする仕組み ◦ Multiple Back Stacks などの実装を隠蔽し、各画面が意図している画面遷移実装に集中でき るようにする
今後の課題 • Jetpack Navigation Component を利用していないこと • Navigation Component は必須ではないと感じているが、長期的なメンテナンス
コストを考えると公式が推している仕組みに近づけた方が良さそう • Navigation Component のマルチモジュールサポートは自作コンポーネントを 完全に置き換えられないため、しばらくは自作した仕組みを Navigation Component に寄せやすくする改良をしていくかも ◦ Navigation best practices for multi-module projects ◦ モジュール間遷移がディープリンク前提、 SafeArgs 使えないという制約は結構辛い
おわり