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
660
クックパッドマートAndroid 徹底解剖
2019/4/24 (Wed) Cookpad Mart Meetup #2
もん
April 24, 2019
Tweet
Share
More Decks by もん
See All by もん
令和に始めるcode generation
litmon
0
150
Cookpad Summer Internship 2019 Day4 Android
litmon
0
10k
Google Play Consoleのリリーストラックを有効活用してリリースフローの最適化を行った話
litmon
2
5k
alpha-release-automation
litmon
2
4.9k
クックパッドアプリのリリースフローに関して
litmon
0
2.2k
AccessibilityServiceを使ってアプリの可能性を広げよう
litmon
1
2.6k
Other Decks in Programming
See All in Programming
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
200
Zendeskのチケットを Amazon Bedrockで 解析した
ryokosuge
3
270
CSC305 Summer Lecture 12
javiergs
PRO
0
130
アプリの "かわいい" を支えるアニメーションツールRiveについて
uetyo
0
110
速いWebフレームワークを作る
yusukebe
5
1.7k
AIコーディングAgentとの向き合い方
eycjur
0
250
KessokuでDIでもgoroutineを活用する / Go Connect #6
mazrean
0
140
TROCCO×dbtで実現する人にもAIにもやさしいデータ基盤
nealle
0
430
もうちょっといいRubyプロファイラを作りたい (2025)
osyoyu
0
240
Langfuseと歩む生成AI活用推進
licux
3
330
Claude Codeで実装以外の開発フロー、どこまで自動化できるか?失敗と成功
ndadayo
4
1.9k
Flutter with Dart MCP: All You Need - 박제창 2025 I/O Extended Busan
itsmedreamwalker
0
130
Featured
See All Featured
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.4k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
48
9.7k
Build your cross-platform service in a week with App Engine
jlugia
231
18k
Optimizing for Happiness
mojombo
379
70k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
51
5.6k
Code Reviewing Like a Champion
maltzj
525
40k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
252
21k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.5k
Optimising Largest Contentful Paint
csswizardry
37
3.4k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
285
13k
Java REST API Framework Comparison - PWX 2021
mraible
33
8.8k
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アプリ開発でつらかったことを紹介 • つらいだけじゃなく楽しいこともたくさんあるよ! • これからも色々と試していきたい • (ボツスライドは要望があれば公開します)