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
Android Architecture Componentsを使ってリファクタリングした話
Search
Yoshihisa
June 26, 2018
Programming
1.8k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Android Architecture Componentsを使ってリファクタリングした話
shibuya.apk#26
Yoshihisa
June 26, 2018
More Decks by Yoshihisa
See All by Yoshihisa
OkHttp3+Retrofit2+...
yoshihisa
0
4.7k
Other Decks in Programming
See All in Programming
LoopHub - ローカルで動く GitHub で、AI と共同開発
jugyo
1
560
Are APIs Still Relevant in the AI Era?
soyuka
0
270
GKE で Pod の見方を変えたら、スケールアウト時の挙動を真に捉えられた話
stkk
0
130
AIは賢い。でも実行環境は? CLIおじさんがAI時代に伝えたいこと ~ CLIおじさんがAI時代に伝えたいこと ~
curekoshimizu
1
250
選挙速報を多くのユーザーへ 届ける Live Activities 設計
hamayokokuririn
0
150
個人開発基盤をまるごとCloudflareに引っ越して爆速で総合的体験を向上させた話
tinykitten
0
200
What We Talk About When We Talk About XP
m_seki
2
660
標準パッケージに uuid が追加された 背景から見る Go らしい意思決定 / go_127_uuid_decision
convto
5
7.5k
Jetpack Compose メカニズム
skydoves
0
450
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
210
App Storeの外へ──日本のiOSサイドローディング入門 for iOSDC Japan 2026
yuukiw00w
0
220
変化を抱擁するドキュメントの作り方 - ビジネスルール駆動開発がもたらす、コードとの新しい関係
ioki
2
220
Featured
See All Featured
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
990
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
470
Marketing to machines
jonoalderson
1
5.8k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
4.9k
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
540
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
910
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
280
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
760
Crafting Experiences
bethany
1
350
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.4k
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
2
430
Transcript
Android Architecture Componentsを 使ってリファクタリングした話
• Yoshihisa Takeda • Twitter: @bomneko_attack • 株式会社Diverse ◦ YYC
Androidアプリ開発 ◦ Androidデビューから1年経過 • 光の戦士 ◦ ララフェル♀ 白魔道士
メッセージ履歴画面 • ユーザ間のメッセージのやりとりをチャット風に表示する • ユーザの状態(性別/年齢確認(18歳以上かの確認)/これ までのやりとりの有無等)で表示が変わる ◦ スクショは女性で年齢確認済みかつ相手の男性にこれまでメー ルを送ったことがない人
(旧)構造 • Activity ◦ メッセージ履歴を表示する RecyclerView + Adapter ◦ ユーザのプロフィール取得
(写真とか性別とか) ◦ メッセージ取得 ◦ メッセージ送信 • メッセージ入力フォームFragment ◦ 各種のボタン(画像添付/スペシャルメール/テンプレート) ▪ スペシャルメールボタンをタップすると初回は説明表示があるため Activityにコールバック ◦ 入力フィールドと送信ボタン ▪ バリデーション ▪ 送信ボタンをタップすると Activityにコールバックされ送信される
(旧)構造
既にやばい香りがする
そこに… • Ver2.9.23: 女性向け新機能 スタンプ送信機能追加 • ただし条件付き ◦ 送信先は男性のみ ◦
送信先の男性に一度もメールを送ったことがない • UI ◦ スタンプのパレットをフォームの上に吹き出す感じで ◦ 入力フォームの切替ボタンを押すとパレットが開いたり閉じたり ◦ パレットが開いている状態だと切替ボタンの色が赤色になる
構造 • Activity ◦ メッセージ履歴を表示するRecyclerView + Adapter ◦ ユーザのプロフィール取得(写真とか性別とか) ◦
メッセージ取得 ◦ メッセージ送信 • メッセージ入力フォームFragment ◦ 各種のボタン(画像添付/スペシャルメール/テンプレート/スタンプパレット) ▪ スペシャルメールボタンをタップすると初回は説明表示があるためActivityにコールバック ▪ スタンプパレットボタンをタップするとパレットの表示切替のためActivityにコールバック ◦ 入力フィールドと送信ボタン ▪ バリデーション ▪ 送信ボタンをタップするとActivityにコールバックされ送信される • スタンプパレットFragment ◦ 送信できるスタンプをサーバから取得 ◦ スタンプをタップするとActivityにコールバックされ送信される
ver2.9.23構造
他にも… • 年齢確認の有無による表示切替 ◦ メッセージ本文が読めない (ブラーがかかる) ◦ メッセージの送信に制限がある
地獄爆誕
どうしてこんなことに… • 典型的なFat Activity • (当時)ActivityとFragmentでロジックと状態を共有するベストな解決策が思いつかな かった • リファクタリングに取り組む時間がなくこの仕組みの上に機能改修を行っていった
どうしてこんなことに… • 典型的なFat Activity • (当時)ActivityとFragmentでロジックと状態を共有するベストな解決策が思いつかな かった • リファクタリングに取り組む時間がなくこの仕組みの上に機能改修を行っていった Android
Architecture Components View Model + LiveData
ViewModel & LiveData • ViewModel(以下, VM) ◦ Activityが回転したときのデータ保持 ◦ 複数のフラグメント間とのデータ共有
• LiveData ◦ Lifecycleに従っていい感じにしてくれるデータホルダー ◦ Lifecycle OwnerがSTARTEDまたはRESUMEDのときのみアクティブになり値を通知してくれる ▪ 非同期処理でありがちな「処理が完了して値を通知し UIを操作しようとしたけれど非アクティ ブになっていてクラッシュ」がない
さぁやるぞ! • リファクタリングが失敗する要因 ◦ 既存のコードを理解しないまま手を付ける ◦ いきなり全部キレイにしようとする ◦ カッとなって全部書き直そうとする •
ひとまず手を付けるところを決めよう
方針 • まず送信に関係する状態とロジックをViewModelに分離することを目指す ◦ プロフィール取得・履歴取得とは独立していた ◦ 送信状態で取り得る状態は画面全体の表示状態と関連が薄かった ▪ 送信中は送信ボタンが消えて代わりにプログレスが表示される ▪
送信完了後スタンプパレットとスタンプパレット表示切り替えボタンを非表示にして履歴をリ ロードする • VMはステートマシンとして実装する ◦ 他の画面で実績があった ◦ 状態を保持するホルダーに LiveDataを使う ▪ (正直なところ)使ってみたかっただけ ▪ ライフサイクルに正しくバインドできれば Rxでも良い • 新規クラスのVM周りはKotlinで、既存クラスはJavaのまま我慢
状態の落とし込み 失敗したときに例外を一緒に持たせたいので enum classではなくsealed classで定義する
ViewModelの実装 • 使うLiveDataは2つ ◦ MutableLiveData: 内部ではコイツに値を postする. 外から値を変更されたくないので公開しない ◦ LiveData:
外部公開用. 使う側はコイツをObserveする ◦ 初期値はコンストラクタでセットしておく
• LiveDataが抱えている状態が「送信中」なら何もしない ◦ 「getValue」メソッドで今抱えている値を取り出せる • 送信中以外の場合は状態を「送信中」にセット • APIのレスポンスに応じて LiveDataに状態をセット ◦
setValue: UIスレッドのみ. IOスレッドで呼ぶと例外 ◦ postValue: IOスレッドでも使える ◦ このコードではIOスレッドで状態をセットするので「 postValue」
• ViewModelが死ぬときに呼び出される • サブスクリプションをクリアする等後始末をするのに使う
ViewModel Factory • ViewModelのコンストラクタに引数を渡すときに使う ◦ ViewModelは直接newしてはいけない
処理の移動と状態遷移の追跡 • ActivityのonCreateでVMを生成 • メッセージ入力フォームとスタンプパレットでActivityの送信メソッドを読んでいる箇 所をVMの送信メソッドを呼ぶように変更 • VMがもっている送信状態をActivityと各FragmentのそれぞれでObserveして状態 に応じてUI等を変更する処理を実装する
VMの初期化 • ActivityのonCreateでFactoryを指定してVMを生成 • VMの状態を抱えているLiveDataをObserveしてハンドリング ◦ Activityがアクティブでないと通知してこない • Javaにもwhen式とスマートキャストをくれ
FragmentでVMを使う • 親Activityがオーナーになっている送信 VMを取得する • FragmentでもVMの状態をハンドリングする • Javaにもwhen式とスマートキャストをくれ(大事なことなので(ry)
ver2.9.23構造
リファクタ後の構造
リファクタリングの結果 • 送信に関する責務をVMに追い出し ◦ 各FragmentはVMが抱えている状態を監視して表示などを変更するように (多少は)キレイになった!!!!
送信機能以外の部分について • プロフィール・メッセージ履歴取得部分についても 同様のアプローチでリファクタリングした ◦ プロフィールとメッセージ履歴は画面表示の状態に密に関連していたので 1つのVM • Activityの行数: 651
ー> 488 ◦ Activityが抱えていたInput Form FragmentやStamp Palette Fragmentの状態決定を それぞれのFragmentで行うように ◦ 機能の追加・改修もある程度しやすくなった (はず)
None
まとめ • Android Architecture Components ViewModelはいいぞ ◦ Activityの回転時のデータ保持 ◦ Fragment間のデータ共有
• リファクタリングするときは方針を決めよう ◦ ときには泥臭く地道にやっていきも大事 ◦ 進めているうちにさらに良い解が見つかることもあるので随時軌道修正
参考資料 • Architecture Components https://developer.android.com/topic/libraries/architecture/ ◦ ViewModel https://developer.android.com/topic/libraries/architecture/viewmodel ◦ LiveData
https://developer.android.com/topic/libraries/architecture/livedata