Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
クックパッドマートAndroid 徹底解剖
Search
もん
April 24, 2019
Programming
1
630
クックパッドマートAndroid 徹底解剖
2019/4/24 (Wed) Cookpad Mart Meetup #2
もん
April 24, 2019
Tweet
Share
More Decks by もん
See All by もん
令和に始めるcode generation
litmon
0
130
Cookpad Summer Internship 2019 Day4 Android
litmon
0
9.8k
Google Play Consoleのリリーストラックを有効活用してリリースフローの最適化を行った話
litmon
2
4.8k
alpha-release-automation
litmon
2
4.8k
クックパッドアプリのリリースフローに関して
litmon
0
2.1k
AccessibilityServiceを使ってアプリの可能性を広げよう
litmon
1
2.5k
Other Decks in Programming
See All in Programming
MCP with Cloudflare Workers
yusukebe
2
220
create_tableをしただけなのに〜囚われのuuid編〜
daisukeshinoku
0
260
StarlingMonkeyを触ってみた話 - 2024冬
syumai
3
270
コンテナをたくさん詰め込んだシステムとランタイムの変化
makihiro
1
130
今年一番支援させていただいたのは認証系サービスでした
satoshi256kbyte
1
260
Effective Signals in Angular 19+: Rules and Helpers
manfredsteyer
PRO
0
110
快速入門可觀測性
blueswen
0
370
数十万行のプロジェクトを Scala 2から3に完全移行した
xuwei_k
0
280
선언형 UI에서의 상태관리
l2hyunwoo
0
170
Scalaから始めるOpenFeature入門 / Scalaわいわい勉強会 #4
arthur1
1
330
useSyncExternalStoreを使いまくる
ssssota
6
1.1k
開発者とQAの越境で自動テストが増える開発プロセスを実現する
92thunder
1
190
Featured
See All Featured
Faster Mobile Websites
deanohume
305
30k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
32
2.7k
Raft: Consensus for Rubyists
vanstee
137
6.7k
Building Applications with DynamoDB
mza
91
6.1k
Building a Modern Day E-commerce SEO Strategy
aleyda
38
7k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
28
4.4k
Reflections from 52 weeks, 52 projects
jeffersonlam
347
20k
Bootstrapping a Software Product
garrettdimon
PRO
305
110k
A designer walks into a library…
pauljervisheath
204
24k
YesSQL, Process and Tooling at Scale
rocio
169
14k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
How GitHub (no longer) Works
holman
311
140k
Transcript
クックパッドマートAndroid 徹底解剖 買物事業部 門田福男
自己紹介 2016年 新卒入社 技術部モバイル基盤グループ→買物事業部 Android エンジニア Twitter: @_litmon_ GitHub :
@litmon
None
クックパッドマートアプリ • アプリ内で商品を閲覧・注文・受け取りが行えるアプリ ◦ 受け取り場所を選択 ◦ 商品を選択 ◦ 商品を購入 ◦
受け取り • ユーザーから見たときにはシンプルな買い物サービスになっている
今日の内容 • クックパッドマートアプリのソースコードを読みながら、 誰でもAndroidアプリ開発が分かった気になれる話をします
今日の内容 • クックパッドマートアプリのソースコードを読みながら、 誰でもAndroidアプリ開発が分かった気になれる話をします ではなく!!!
今日の内容 • クックパッドマートの開発を行っていく上で困った点と、どう解決したかを 紹介していきます ◦ UI構築のつらみ ◦ 非同期処理のつらみ ◦ おまけ:技術選定のつらみ
今日の内容 • クックパッドマートの開発を行っていく上で困った点と、どう解決したかを 紹介していきます ◦ UI構築のつらみ ◦ 非同期処理のつらみ ◦ おまけ:技術選定のつらみ
つまらなかったのでボツになりました
UI構築のつらみ
• 各画面のレイアウトを組む方法 • ボトムナビゲーションへの要求とライブラリ • CollapsingToolbarLayoutを使ったカッコいいUI UI構築でのつらみ
• 各画面のレイアウトを組む方法 • ボトムナビゲーションへの要求とライブラリ • CollapsingToolbarLayoutを使ったカッコいいUI UI構築でのつらみ
• どうつらいのか、どう解決したのかを含めて技術ブログで解説 https://techlife.cookpad.com/entry/2019/04/11/130000 • 各画面のレイアウトを組む方法
• 各画面のレイアウトを組む方法 • ボトムナビゲーションへの要求とライブラリ • CollapsingToolbarLayoutを使ったカッコいいUI UI構築でのつらみ
• 下の白いバー部分のことを指す ◦ マテリアルデザインでも定義されている ◦ https://material.io/design/components/bottom-navigation.html • 公式のライブラリでは BottomNavigationView というものが提供されていて、マテリアルデザ
インに沿ったものが簡単に実装できるように なっている • はずだった・・・ ボトムナビゲーション
• 公式の提供しているライブラリには、バッヂを 付ける方法が提供されていない(!!) つらみ1:バッヂがつかない
• 公式の提供しているライブラリには、バッヂを 付ける方法が提供されていない(!!) • https://material.io/design/components/bottom-navigation.html つらみ1:バッヂがつかない
つらみ1:バッヂがつかない • 公式の提供しているライブラリには、バッヂを 付ける方法が提供されていない(!!) • https://material.io/design/components/bottom-navigation.html 公式とはいったいなんだったのか・・・
• サードパーティの有名なライブラリが見つかる ◦ https://github.com/aurelhubert/ahbottomnavigation • 無事にバッヂを付けられそう・・・ つらみ1 解決
デザイナー「カートのアイコン、アニメーションしたい なぁ・・・」
私「!?お、おう・・・」
デザイナー「あっ!無理ならいいんだよ、無理なら」 私(ここで無理なんて言いたくないなぁ…) 私「カンガエマス」
• カートに商品が追加されたときに、より分かりやすく表現したい • マテリアルデザインでもアイコンアニメーションは定義されている ◦ https://material.io/design/iconography/animated-icons.html#usage つらみ2:アイコンのアニメーション
• Lottieを使ってアニメーションを作りたい ◦ https://airbnb.design/lottie/ ◦ ViewをLottie用に対応させる必要がある • \(^o^)/ つらみ2:アイコンのアニメーション
• どうしようもなかったので自作した • 技術選定の基本方針は「出来るだけ公式に提供されているものを使う」だっ たが、ないものは仕方ないのでやった ◦ 自分で作ったりサードパーティライブラリにすると、 メンテナンスされなくて負債になりがちなのであまりやりたくなかった 解決策: 自作する
解決策: 自作する
解決策: 自作する
解決策: 自作する
• それなりに大変だったが、それらしいものが出来たので満足 • ちなみにカートのアイコンアニメーションは様々な事情によりまだ実装され ていません ◦ \(^o^)/ 自作した結果
• 各画面のレイアウトを組む方法 • ボトムナビゲーションへの要求とライブラリ • CollapsingToolbarLayoutを使ったカッコいいUI UI構築でのつらみ
• Toolbar(上部のバー)に画像を入れて、スクロー ル時にいい感じにかっこよくなるやつ • 公式で提供されているコンポーネント • 開いているとき(Expanded)と 閉じているとき(Collapsed)で見た目を変える ◦ Expanded:
画像が表示される ◦ Collapsed: タイトルが表示される • 特にデザイナーに言われたわけでなく良さそう だったから使ってみた CollapsingToolbarLayout
• Fragmentでの画面遷移と相性が悪い ◦ Fragmentで画面遷移を行い、元の画面に戻る挙動を実装 すると、画面が再生成される ◦ 通常は再生成時にそれぞれのViewがいい感じに状態を復 元する • ボトムナビを切り替えるだけで発生するので、
マストで対応したい CollapsingToolbarLayoutのつらみ
• 「CollapsingToolbarLayoutがどれくらいスクロールされてるか取れたり設定 出来たりするのでは?」 ◦ 出来ない • 「今の状態(Expanded/Collapsed)を取得して復元すれば良いのでは?」 ◦ 取れない •
「画像が読み込まれるのが問題なのでExpandしたときだけ読み込めば?」 ◦ 画像を読み込まなくても真っ赤なToolbarが残るだけ • • \(^o^)/ CollapsingToolbarLayoutのつらみ
• CollapsingToolbarLayoutそのものから情報を取ることは出来ないことがわ かったので、画面全体のスクロール状態を取得して「今Expandしているか」 を判定することに ◦ RecyclerViewのスクロール状態の判定もトリッキーだったのでここでさらに苦戦・・・ • 画面復元時にExpanded, Collapsedの状態を復元することにした 最終的な解決策
• CollapsingToolbarLayoutそのものから情報を取ることは出来ないことがわ かったので、画面全体のスクロール状態を取得して「今Expandしているか」 を判定することに ◦ RecyclerViewのスクロール状態の判定もトリッキーだったのでさらに苦戦・・・ • 画面復元時にExpanded, Collapsedの状態を復元することにした 最終的な解決策
• 中途半端にスクロールすると、文字が微妙に表示 されててきもちわるい • 閉じた状態で画面移動すると、一瞬だけ画像が読 み込まれるのが見えてきもちわるい 解決策求む! (CollapsingToolbarLayoutやめたい…) 未解決問題
非同期処理のつらみ
クックパッドマートのAPIサーバー • クックパッドマートのAPIサーバーには garage を使用している ◦ https://github.com/cookpad/garage ◦ RESTful APIを実現するためのRuby
on Rails用のgem • garage では、APIのレスポンスをクライアントから操作することが出来る ◦ fields というクエリパラメータを指定することで、必要なデータを必要なだけ取得することが 可能
たとえば /v1/product_tags/100?fields=name,products[id,name] というAPIリクエストを送ると、右のような レスポンスJSONが返却される
たとえば コード上ではdata classで表現してJSONからオブジェクトを生成
たとえば 逆にいうと、data classからリクエストするときに必要なfieldsが分かる
fieldsのつらみ • 必要なデータが増えれば増えるほど、fields文字列が長く複雑に ◦ 右の画像のようなdata classになったらすごいつらい ◦ APIエンドポイントが増えるたびにやる必要があってすごいつらい • 手作業でやっていくと非常に手間がかかる
&& ミスも起きやすい ◦ typoによるデータ取得失敗 ◦ データの増減によるfields文字列のメンテナンス • 長い文字列は精神的な消耗が激しい ◦ fields=id,name,summary,price,items[specifications[label,text]],... ◦ やってられない\(^o^)/
解決策: 文字列を自動生成する • annotationProcessorと呼ばれるコード生成機構が存在する • 最近はリフレクションの代わりにコード生成するようなライブラリが一般的 ◦ リフレクションよりもランタイム時の動作が軽量で高速 • 機械的に生成すれば、消耗も少なくて済む!
解決策: 自動生成する こんなかんじでコード生成用のgeneratorを作成
解決策: 自動生成する data classから右のようなコードが自動生成されて
解決策: 自動生成する 文字列を自分で作る必要がなくなった! before after
自作してみて • 機械的に生成出来るようになってストレスフリー ◦ 人為的なミスが発生する箇所はdata class上でのtypoのみになった ◦ garage を使っている全人類に使って欲しい •
annotationProcessorはライブラリでよく使われるが、 必要に応じて自分で作ってみるのも意外といい ◦ annotationProcessorの気持ちになれた ◦ 「ライブラリほど汎用的には出来ないけどプロジェクト固有のコードを機械的に生成した い」という要求は他にもありそう
APIリクエストに関する未解決問題 • fields を指定しても、正しく返ってくる保証がない ◦ サーバー側で定義されていない可能性もある ◦ 正しいかどうかを検知する手段が(現状)ない • Kotlinのコードにマッピングする際にはnull安全性を考慮する必要がある
◦ Kotlinはnon-nullな型とnullableな型が別で定義されている ◦ JSONからパースする際にnon-nullな型に何も入らない or nullが入ると、エラーが返る • 候補策は巷にいくつかあるが、着手出来ていない ◦ JSON Schema? Swagger? GraphQL? Protocol Buffer? BFF?
おまけ 技術選定のつらみ
最近のAndroidアプリ開発事情 • 最近はGoogleが公式で提供するライブラリがとても優秀なものが増えてきた ◦ WorkManager ◦ Navigation ◦ LiveData ◦
ViewModel • これまでの開発歴史上「ツライ」と言われていた部分を解決する
しかし・・・ • アルファ版が多い!アルファが取れない!! • 技術選定の基本条件に「出来るだけ安定版を使う」としていたためどうして も採用に踏み切れない • 特に画面遷移をいい感じに解決できるNavigationライブラリの導入はまだ出 来ていない ◦
現状のアプリ構成とNavigationのデフォルト挙動が噛み合わなくて踏み切れない
しかし・・・ • アルファ版が多い!アルファが取れない!! • 技術選定の基本条件に「出来るだけ安定版を使う」としていたためどうして も採用に踏み切れない • 特に画面遷移をいい感じに解決できるNavigationライブラリの導入はまだ出 来ていない ◦
現状のアプリ構成とNavigationのデフォルト挙動が噛み合わなくて踏み切れない https://developer.android.com/jetpack/androidx/releases/navigation ようやく・・・
まとめ
まとめ • Androidアプリ開発でつらかったことを紹介 • つらいだけじゃなく楽しいこともたくさんあるよ! • これからも色々と試していきたい • (ボツスライドは要望があれば公開します)