Slide 1

Slide 1 text

ZOZOTOWNでの
 Dagger Hilt対応について
 2020/12/18(Fri)
 【Sansan Tech Meetup】Android開発Tipsを3社のエンジニアが語る
 株式会社ZOZOテクノロジーズ
 ZOZOTOWN部 Androidチーム Tech Lead
 堀江 亮介 Copyright © ZOZO Technologies, Inc.

Slide 2

Slide 2 text

© ZOZO Technologies, Inc. 株式会社ZOZOテクノロジーズ
 ZOZOTOWN部 Androidチーム
 Tech Lead 堀江 亮介
 ● 自動化とビールが好き ● @Horie1024 ● 昔Androidテスト全書という本を書きました 
 2

Slide 3

Slide 3 text

© ZOZO Technologies, Inc. https://zozo.jp/
 ● 日本最大級のファッション通販サイト
 ● 1,300以上のショップ、7,600以上のブランドの取り扱い(ともに2020年3 月末時点)
 ● 常時83万点以上の商品アイテム数と毎日平均3,000点以上の新着 商 品を掲載
 ● 即日配送サービス
 ● ギフトラッピングサービス
 ● ツケ払い など


Slide 4

Slide 4 text

© ZOZO Technologies, Inc. 4 ● Dagger Hiltへマイグレーションするモチベーション
 ● どのようなマイグレーション作業を行ったか
 ● 作業を行う中で躓いたポイント
 今日話すこと


Slide 5

Slide 5 text

© ZOZO Technologies, Inc. 5 ● DI(依存性の注入)とは何か
 ● Daggerの詳細
 ● Dagger Hiltの詳細
 今日話さないこと


Slide 6

Slide 6 text

© ZOZO Technologies, Inc. 6 Daggerを利用する中で感じた課題
 
 
 ● 学習コスト
 ○ DI + Dagger + AndroidアプリでのDaggerの使用方法


Slide 7

Slide 7 text

© ZOZO Technologies, Inc. 7 Daggerを利用する中で感じた課題
 
 
 ● 学習コスト
 ○ DI + Dagger + AndroidアプリでのDaggerの使用方法
 ● 設計で迷う
 ○ 自由度が高く、ベストプラクティスがわからない
 ○ 例: Subcomponents vs. Component dependencies
 ■ コンポーネントの構成・設計をどうするか?
 ■ Injectのタイミングは?


Slide 8

Slide 8 text

© ZOZO Technologies, Inc. 8 Daggerを利用する中で感じた課題
 
 
 ● 学習コスト
 ○ DI + Dagger + AndroidアプリでのDaggerの使用方法
 ● 設計で迷う
 ○ 自由度が高く、ベストプラクティスがわからない
 ○ 例: Subcomponents vs. Component dependencies
 ■ コンポーネントの構成・設計をどうするか?
 ■ Injectのタイミングは?
 ● ボイラープレートなコードの増加


Slide 9

Slide 9 text

© ZOZO Technologies, Inc. 9 ● 学習コスト
 ○ DI + Dagger + AndroidアプリでのDaggerの使用方法
 ● 設計で迷う
 ○ 自由度が高く、ベストプラクティスがわからない
 ○ 例: Subcomponents vs. Component dependencies
 ■ コンポーネントの構成・設計をどうするか?
 ■ Injectのタイミングは?
 ● ボイラープレートなコードの増加
 Daggerを利用する中で感じた課題
 
 
 Dagger Hiltなら課題を改善できるか?

Slide 10

Slide 10 text

© ZOZO Technologies, Inc. Dagger Hiltとは?
 10

Slide 11

Slide 11 text

© ZOZO Technologies, Inc. 11 “Hiltは、プロジェクト内のすべてのAndroidクラスにコンテナを提供し、そのラ イフサイクルを自動で管理することで、アプリケーションでDIを行うための標 準的な方法を提供します。Hiltは、よく知られた DIライブラリであるDaggerの 上に構築されているため、コンパイル時の正確性、実行時のパフォーマン ス、スケーラビリティ、Android StudioのサポートといったDaggerの恩恵を受 けられます。”
 Dagger Hiltとは?
 引用: Hilt を使用した依存関係の注入 Android Developers https://developer.android.com/training/dependency-injection/hilt-android

Slide 12

Slide 12 text

© ZOZO Technologies, Inc. 12 ● Dagger上に構築されたDIライブラリ
 ● Android開発に特化
 ● Androidアプリ開発におけるDIを標準化
 Dagger Hiltとは?


Slide 13

Slide 13 text

© ZOZO Technologies, Inc. ● 制約と一貫性
 ○ Hiltの制約に従うことで一貫性が生まれる
 ○ 考慮すべき点が減り設計に迷わない
 13 HiltによるAndroidアプリ開発におけるDIの標準化


Slide 14

Slide 14 text

© ZOZO Technologies, Inc. ● 制約と一貫性
 ○ Hiltの制約に従うことで一貫性が生まれる
 ○ 考慮すべき点が減り設計に迷わない
 ● 学習すべき内容が整理され絞られる
 ○ DI + Dagger + HiltでのAndroidクラスへのDI方法
 ○ 結果的に学習コストが減少
 14 HiltによるAndroidアプリ開発におけるDIの標準化


Slide 15

Slide 15 text

© ZOZO Technologies, Inc. ● 制約と一貫性
 ○ Hiltの制約に従うことで一貫性が生まれる
 ○ 考慮すべき点が減り設計に迷わない
 ● 学習すべき内容が整理され絞られる
 ○ DI + Dagger + HiltでのAndroidクラスへのDI方法
 ○ 結果的に学習コストが減少
 ● AndroidフレームワーククラスへのDI方法の標準化
 ○ ボイラープレートなコードが減少
 15 HiltによるAndroidアプリ開発におけるDIの標準化


Slide 16

Slide 16 text

© ZOZO Technologies, Inc. ● Daggerの利用で感じていた課題の改善を期待
 16 Dagger Hiltへのマイグレーションのモチベーション


Slide 17

Slide 17 text

© ZOZO Technologies, Inc. ● Daggerの利用で感じていた課題の改善を期待
 ○ 学習コストの削減
 ○ 設計の迷いをなくし機能の開発に集中
 ○ ボイラープレートなコードの削減
 17 Dagger Hiltへのマイグレーションのモチベーション


Slide 18

Slide 18 text

© ZOZO Technologies, Inc. ● Daggerの利用で感じていた課題の改善を期待
 ○ 学習コストの削減
 ○ 設計の迷いをなくし機能の開発に集中
 ○ ボイラープレートなコードの削減
 ● それによるチームの生産性向上
 ○ 素早いリリースと価値検証の実現
 18 Dagger Hiltへのマイグレーションのモチベーション


Slide 19

Slide 19 text

© ZOZO Technologies, Inc. マイグレーションの流れ
 19

Slide 20

Slide 20 text

© ZOZO Technologies, Inc. ● 次の2段階でマイグレーションを進めた
 ○ Dagger Hiltについての学習
 ○ マイグレーションの実施
 20 マイグレーションの流れ


Slide 21

Slide 21 text

© ZOZO Technologies, Inc. ● Dagger Hiltについての学習
 ● マイグレーションの実施
 21 マイグレーションの流れ


Slide 22

Slide 22 text

© ZOZO Technologies, Inc. ● Dagger Hiltについての学習
 ● マイグレーションの実施
 22 マイグレーションの流れ


Slide 23

Slide 23 text

© ZOZO Technologies, Inc. ● Dagger Hiltについての理解を深める
 ● マイグレーションの方法について学ぶ
 ● 具体的に行った内容
 ○ Codelabの実施
 ○ 各種資料の確認
 ○ OSSのHiltマイグレーションのPull Requestを確認
 23 Dagger Hiltについての学習


Slide 24

Slide 24 text

© ZOZO Technologies, Inc. ● Codelab会でDagger HiltのCodelabをチーム全員で実施
 24 Dagger Hiltについての学習: Codelabの実施


Slide 25

Slide 25 text

© ZOZO Technologies, Inc. ● Using Hilt in your Android app
 ○ AndroidアプリでのDagger Hiltの基本的な使い方
 ○ https://codelabs.developers.google.com/codelabs/android-hilt/?hl=ja#0
 ○ 日本語訳した資料
 ○ https://scrapbox.io/horie1024-pub/【Codelab】Using_Hilt_in_your_Android_app_メモ
 ● Migrating your Dagger app to Hilt
 ○ Daggerを使用するアプリをステップバイステップでHiltへマイグレーションする方法を学ぶ
 ○ https://developer.android.com/codelabs/android-dagger-to-hilt#0
 ○ 日本語訳した資料
 ○ https://scrapbox.io/horie1024-pub/【Codelab】Migrating_your_Dagger_app_to_Hiltメモ
 
 25 Dagger Hiltについての学習: Codelabの実施


Slide 26

Slide 26 text

© ZOZO Technologies, Inc. 26 ● Hiltを使用した依存関係の注入 Android Developers
 ○ まずDagger Hiltの概要を掴むのに最適
 ○ https://developer.android.com/training/dependency-injection/hilt-android
 ● Dagger Hilt (DevFest 2020 資料)
 ○ DIの概要からHiltの実践tipsまでまとまった非常に参考になる資料
 ○ https://qiita.com/takahirom/items/46053e031041405e2a9e
 ● dagger.dev/hilt
 ○ より詳細なHiltのドキュメント
 ○ https://dagger.dev/hilt/
 Dagger Hiltについての学習: 各種資料の確認


Slide 27

Slide 27 text

© ZOZO Technologies, Inc. 27 ● dagger.dev/hilt/migration-guide
 ○ Hiltへのマイグレーションガイド
 ○ マイグレーションの進め方についての丁寧な解説
 ○ https://dagger.dev/hilt/migration-guide
 
 Dagger Hiltについての学習: 各種資料の確認


Slide 28

Slide 28 text

© ZOZO Technologies, Inc. 28 ● google/iosched
 ○ PRではなくcommit。dagger.androidからのマイグレーション
 ○ https://github.com/google/iosched/commit/9c20fdd52d446e5fdb03369e50fb196c31ae16e3
 ● chrisbanes/tivi
 ○ https://github.com/chrisbanes/tivi/pull/640
 ● android/sunflower
 ○ https://github.com/android/sunflower/pull/623
 ● android/architecture-samples
 ○ https://github.com/android/architecture-samples/pull/739
 
 Dagger Hiltについての学習: マイグレーションPRの確認


Slide 29

Slide 29 text

© ZOZO Technologies, Inc. ● マイグレーションについてはこの2つを押さえる
 ○ Codelab: Migrating your Dagger app to Hilt
 ○ dagger.dev/hilt/migration-guide
 ● マイグレーションの概要を把握後は?
 ○ 実際にマイグレーションを実施
 29 Dagger Hiltについての学習


Slide 30

Slide 30 text

© ZOZO Technologies, Inc. ● Dagger Hiltについての学習
 ● マイグレーションの実施
 30 マイグレーションの流れ
 
 


Slide 31

Slide 31 text

© ZOZO Technologies, Inc. ● Dagger Hiltについての学習
 ● マイグレーションの実施
 31 マイグレーションの流れ
 
 


Slide 32

Slide 32 text

© ZOZO Technologies, Inc. ● 具体的に何をするのか?
 ○ Migrating to Hiltの「Migration Overview」に書かれている
 32 マイグレーションの実施
 引用: Migrating to Hilt Migration Overview https://dagger.dev/hilt/migration-guide#migration-overview

Slide 33

Slide 33 text

© ZOZO Technologies, Inc. ● ZOZOTOWNのマイグレーションに必要な作業
 ○ すべての@Component/@Subcomponentの削除
 ○ すべての@Moduleクラスに@InstallInアノテーションを付ける
 ○ Activity/FragmentといったAndroidフレームワークのクラスに @AndroidEntryPointアノテーションを付ける
 33 マイグレーションの実施


Slide 34

Slide 34 text

© ZOZO Technologies, Inc. ● ZOZOTOWNのマイグレーションに必要な作業
 ○ すべての@Component/@Subcomponentの削除
 ○ すべての@Moduleクラスに@InstallInアノテーションを付ける
 ○ Activity/FragmentといったAndroidフレームワークのクラスに @AndroidEntryPointアノテーションを付ける
 34 マイグレーションの実施


Slide 35

Slide 35 text

© ZOZO Technologies, Inc. ● 既存のコンポーネントを対応するHiltコンポーネントにマッピング
 ○ マッピングしたHiltコンポーネントを@Moduleクラスの
 @InstallInアノテーションで指定
 ● Componentから依存を取得するコードの確認と置換え
 ● コンポーネント引数の確認と置換え
 35 すべての@Component/@Subcomponentの削除


Slide 36

Slide 36 text

© ZOZO Technologies, Inc. ● ZOZOTOWN AndroidはComponent dependenciesで構成
 ● Activity/Fragment/Gradle Module毎にComponentを用意
 36 コンポーネント構成の確認
 App Component Core Component Feature Component Feature Component Feature Component

Slide 37

Slide 37 text

© ZOZO Technologies, Inc. ● Androidクラスに対して自動で生成されるコンポーネント
 37 Hiltコンポーネント
 引用: https://dagger.dev/hilt/components

Slide 38

Slide 38 text

© ZOZO Technologies, Inc. 対応するHiltコンポーネントへのマッピング
 ● App/Core Component → SingletonComponent
 ● Feature Component →
 ActivityComponent または FragmentComponent
 
 38 App Component Core Component Feature Component Feature Component Feature Component

Slide 39

Slide 39 text

© ZOZO Technologies, Inc. ● MainActivityの場合
 ○ 既存のComponentをActivityComponentへマッピング
 ○ @InstallInアノテーションにマッピングしたComponentを指定
 ○ MainActivity内でバインディングが使用可能
 39 @Module @InstallIn(ActivityComponent::class) object MainModule {} @Moduleクラスの@InstallInアノテーションで指定


Slide 40

Slide 40 text

© ZOZO Technologies, Inc. ● Hiltではモノリシックなコンポーネントとなる
 ○ 例: すべてのActivityで1つのコンポーネント共有
 ● @InstallInアノテーションの付与で競合が発生する可能性がある
 ● 競合が発生した場合単一の定義になるようバインディングを再定義
 40 duplicate bindingエラー


Slide 41

Slide 41 text

© ZOZO Technologies, Inc. ● Componentからの依存の取得はEntryPointで置換え
 41 val database = MyApp.getDaggerAppComponent().appDatabase() // EntryPointでの置換え @InstallIn(SingletonComponent::class) @EntryPoint interface AppDatabaseEntryPoint { fun appDatabase(): AppDatabase } val database = EntryPointAccessors .fromApplication(context, AppDatabaseEntryPoint.class).appDatabase() Componentから依存を取得するコードの確認と置換え


Slide 42

Slide 42 text

© ZOZO Technologies, Inc. ● Hiltコンポーネントの初期化は隠蔽され引数をとることができない
 ● ZOZOTOWNの場合ViewModelのバインディングを作成するために Activity/FragmentをComponent引数で@BindInstanceしている
 42 Component引数の確認と置換え
 @Module object MainModule { @ScreenScope @Provides fun provideMainViewModel( activity: MainActivity, factory: MainViewModelFactory ): MainViewModel = ViewModelProvider(activity.viewModelStore, factory) .get(MainViewModel::class.java) }

Slide 43

Slide 43 text

© ZOZO Technologies, Inc. ● ViewModelは by viewModels での作成に変更
 ● ZOZOTOWNではViewModelFactoryを明示的に渡している ○ ViewModelはFragmentComponentにバインドされる ● @ViewModelInjectをViewModelに付与すればFactoryが不要になるが使 用しない
 43 Component引数の確認と置換え
 @Inject lateinit var viewModelFactory: MainViewModelFactory private val viewModel: MainViewModel by viewModels { viewModelFactory }

Slide 44

Slide 44 text

© ZOZO Technologies, Inc. ● @ViewModelInjectを使用するとActivityRetainedComponentに ViewModelがバインドされる
 ● ZOZOTOWNの実装ではViewModelがFragmentComponentにバインドされ た依存を使用する。そのためHiltコンポーネントの階層の制約に違反して しまう
 44 @ViewModelInjectを使用しない理由


Slide 45

Slide 45 text

© ZOZO Technologies, Inc. 45 @ViewModelInjectを使用しない理由
 引用: Hilt Components https://dagger.dev/hilt/components.html 上層から下層へのアクセス不可

Slide 46

Slide 46 text

© ZOZO Technologies, Inc. ● 既存のコンポーネントを対応するHiltコンポーネントにマッピング
 ○ マッピングしたHiltコンポーネントを@Moduleクラスの
 @InstallInアノテーションで指定
 ● Componentから依存を取得するコードの確認と置換え
 ● コンポーネント引数の確認と置換え
 ● ここまでの作業終えると@Component/@Subcomponentが削除可能になる
 46 すべての@Component/@Subcomponentの削除


Slide 47

Slide 47 text

© ZOZO Technologies, Inc. ● ZOZOTOWNのマイグレーションに必要な作業
 ○ すべての@Component/@Subcomponentの削除
 ○ すべての@Moduleクラスに@InstallInアノテーションを付ける
 ○ Activity/FragmentといったAndroidフレームワークのクラスに @AndroidEntryPointアノテーションを付ける
 47 マイグレーションの実施


Slide 48

Slide 48 text

© ZOZO Technologies, Inc. ● ZOZOTOWNのマイグレーションに必要な作業
 ○ すべての@Component/@Subcomponentの削除
 ○ すべての@Moduleクラスに@InstallInアノテーションを付ける
 ○ Activity/FragmentといったAndroidフレームワークのクラスに @AndroidEntryPointアノテーションを付ける
 48 マイグレーションの実施


Slide 49

Slide 49 text

© ZOZO Technologies, Inc. ● Applicationクラスに@HiltAndroidAppを付与
 ○ Hiltのコード生成がトリガーされる
 ● Activity/Fragment/View/Service/BroadcastReceiverへ
 @AndroidEntryPointを付与
 ○ 付与されたクラスはHiltの管理下に入りDIが実行される
 ○ ZOZOTOWNでは既にDaggerの管理下に入っていたクラスのみ
 付与した
 49 Androidクラスへの@AndroidEntryPointアノテーションの付与


Slide 50

Slide 50 text

© ZOZO Technologies, Inc. 50 @HiltAndroidApp class App : Application() @AndroidEntryPoint class MainActivity : AppCompatActivity() { @Inject lateinit var foo: Foo . . } class Foo @Inject constructor() { fun say() = "Hello" } これだけでFooクラスの インスタンスが注入される

Slide 51

Slide 51 text

© ZOZO Technologies, Inc. ● 具体的に何をするのか?
 ○ すべての@Component/@Subcomponentの削除
 ○ すべての@Moduleクラスに@InstallInアノテーションを付ける
 ○ Activity/FragmentといったAndroidフレームワークのクラスに @AndroidEntryPointアノテーションを付ける
 ● ここまでの作業をすべて終えるとマイグレーションが完了
 ○ エラーがでた場合でもHiltのエラーログが見やすいので解決は比較的し やすい
 51 マイグレーションの実施


Slide 52

Slide 52 text

© ZOZO Technologies, Inc. まとめ
 52

Slide 53

Slide 53 text

© ZOZO Technologies, Inc. 53 ● ボイラープレートなコードが消え見通しが良くなった
 ● Codelabや資料が充実しているのでマイグレーションに取組やすい
 ● マイグレーションの難易度はプロジェクトによる
 ○ ZOZOTOWNの場合マイグレーション作業はマイグレーションガイド通り の物が多かった
 まとめ


Slide 54

Slide 54 text

No content