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
710
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
クックパッドマートAndroid 徹底解剖
2019/4/24 (Wed) Cookpad Mart Meetup #2
もん
April 24, 2019
More Decks by もん
See All by もん
令和に始めるcode generation
litmon
0
170
Cookpad Summer Internship 2019 Day4 Android
litmon
0
10k
Google Play Consoleのリリーストラックを有効活用してリリースフローの最適化を行った話
litmon
2
5.3k
alpha-release-automation
litmon
2
5.1k
クックパッドアプリのリリースフローに関して
litmon
0
2.3k
AccessibilityServiceを使ってアプリの可能性を広げよう
litmon
1
2.7k
Other Decks in Programming
See All in Programming
属人化した知識を、 AIが辿れる地図にする
pkshadeck
PRO
1
150
Japan Community Day at Kubecon + CloudNativeCon Japan 2026: Learning Container Privilege Control by Building My Own Low-Level Container Runtime
ternbusty
1
150
AIが無かった頃の素敵な出会いの話
codmoninc
1
390
OpenSpecのproposalにbrainstormingを持たせてみた
tigertora7571
1
210
【やさしく解説 設計編・中級 #1】一つの車に、運転手は一人 ~ある倉庫システムの事例から~
panda728
PRO
0
210
Terraform標準の組織で AWS CDKをどう使うか
mu7889yoon
1
490
仕様駆動開発へのトライを機に チームに適合する手法を模索し続けている話
freee
PRO
0
450
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
540
PHP に部分適用が来るぞ!……ところで何それ?おいしいの? #phpcon / phpcon-2026
shogogg
0
600
20260722_microCMSで考える、AI時代のコンテンツ運用設計
yosh1
0
380
【やさしく解説 設計編・中級 #6】良いアーキテクチャとは ~ 一本の登り道の、行き先 ~
panda728
PRO
0
210
改善しないと、タスクが回らない。 “てんこ盛りポジション” を引き継いだ情シスの、入社3ヶ月の業務改善録
krm963
0
260
Featured
See All Featured
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.4k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
480
Unsuck your backbone
ammeep
672
58k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.2k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
2.9k
SEO for Brand Visibility & Recognition
aleyda
0
4.7k
[SF Ruby Conf 2025] Rails X
palkan
2
1.3k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.3k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.3k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.8k
Context Engineering - Making Every Token Count
addyosmani
9
1k
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アプリ開発でつらかったことを紹介 • つらいだけじゃなく楽しいこともたくさんあるよ! • これからも色々と試していきたい • (ボツスライドは要望があれば公開します)