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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
JPUG勉強会 OSSデータベースの内部構造を理解しよう(第2回)
oga5
0
280
[ハンズオン]AIへの指示だけで「五目並べ」を作ってみよう
satoshi256kbyte
1
310
SONY CISC-NEWS NWS-1750 + NWB-225 フレームバッファの NetBSD/news68k ドライバ実装 / OSC2026Hiroshima
tsutsui
0
160
App Storeの外へ──日本のiOSサイドローディング入門 for iOSDC Japan 2026
yuukiw00w
0
280
IBM Bob Dojo #1 仕様駆動開発入門
oniak3ibm
PRO
0
320
Omarchy Tokyo やると聞いて UMPC 買ってセットアップしてきた
mtsmfm
0
200
ゲームコントローラやキーボードのファームウェアをSwiftで書く
kishikawakatsumi
1
270
更なる可用性を求めて、5年間運用したKotlinのアプリケーションをGoでリプレイスする話
ken_tunc
0
420
パズルゲームの作り方 / how to make puzzle games
kaityo256
PRO
2
260
Unity6 URPによる海底をテーマにしたVJシステムの解説 | Unity Shader 完全に理解した 勉強会
gam0022
0
230
wkhtmltopdfの次どうするか問題2026
willnet
2
1.8k
カツオ、ご期待ください
suneo3476
0
130
Featured
See All Featured
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.4k
Marketing to machines
jonoalderson
1
5.8k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.9k
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
brightonSEO & MeasureFest 2025 - Winning Strategies for Black Friday CRO & PPC - Christian Goodrich
cargoodrich
3
860
Abbi's Birthday
coloredviolet
4
10k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.3k
Test your architecture with Archunit
thirion
2
2.4k
The Curious Case for Waylosing
cassininazir
1
550
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
520
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