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
タップルでたっぷりDaggerを使って マルチモジュール構築している話 :)
Search
Sato Shun
September 10, 2019
Programming
2.7k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
タップルでたっぷりDaggerを使って マルチモジュール構築している話 :)
タップルでたっぷりDaggerを使ってマルチモジュール構築している話です!
Sato Shun
September 10, 2019
More Decks by Sato Shun
See All by Sato Shun
Kotlin Nativeにおけるfrozen状態と並行処理について
satoshun
0
1k
DroidKaigi 2020: System UIをコントロールして、 画面を最大限に生かしたアプリを構築する / Build apps that make the best uses of device screens by controlling System UI
satoshun
4
2k
Kotlin Fest 2019: Kotlin型実践入門
satoshun
9
7.1k
R8/ProGuard 徹底比較
satoshun
8
4.3k
Android: Introduction Android Support Annotations
satoshun
0
160
Android: Daggear2でDI
satoshun
0
200
Other Decks in Programming
See All in Programming
RSSとCodexを使ってX投稿自動化してみた
ochtum
0
110
コンパウンドプロダクト開発のためのローカルプロセスマネージャー再発明 #layerxgo
izumin5210
0
660
業務時間外もAIに働いてもらう話
colorful12
3
10k
PyO3 で既存 Python 評価器を Rust core 化する ー wasm-bindgen でブラウザにも配るための設計
kdash
1
560
スマート反転とウェブアクセシビリティ
camiha
0
170
ALB ログから Trace を気合で繋げる技術
fohte
7
880
ハーネス設計入門 〜プロンプト、コンテキストの次〜
kinopeee
55
36k
iOS開発×AI駆動開発 〜最近使って便利だったスキルの話〜
nogu66
0
140
Kiroで創り、AgentCoreで繋ぐ!AWSで実践する「AI-DLC」から「AIエージェント統合」までの最新地図
licux
3
380
Gmail/Google DriveをトリガーにAIエージェントを動かそう! / Run AI agents with Gmail/Google Drive as triggers!
har1101
3
480
AIを上手に使っていこうとしたら越境せざるを得なくなった話 〜実践1年で見えた境界を越えなければならない理由と進め方〜 / Crossing borders with AI
tomoyakitaura
4
1.1k
まだ間に合う!今年の夏こそSchemeのマクロ展開器を完全理解!
omasanori
0
640
Featured
See All Featured
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
500
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
4.7k
The Language of Interfaces
destraynor
162
27k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
240
Making Projects Easy
brettharned
120
6.7k
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
190
Test your architecture with Archunit
thirion
2
2.4k
Designing Experiences People Love
moore
143
24k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.9k
How to Talk to Developers About Accessibility
jct
2
540
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Transcript
CA.apk #8 ࠤ౻ ൏ / Sato Shun Twitter: @stsn_jp GitHub:
satoshun λοϓϧͰͨͬΓDaggerΛͬͯ ϚϧνϞδϡʔϧߏங͍ͯ͠Δ :)
ँࣙ • λΠτϧɺogaclejapan͞ΜͷɺFlux de Relax :) Λࢀ ߟʹ͓ͯ͠Γ·͢ • https://speakerdeck.com/ogaclejapan/flux-de-relax
ࠓճ͞ͳ͍͜ͱ • DaggerૉΒ͍͠Μͩͧʂ͍ͬͯ͏Ͱͳ͍Ͱ͢ • Koinͱ͔ଞͷϥΠϒϥϦͳͲͷൺֱͰ͋Γ·ͤΜ
ࠓճ͢͜ͱ • Daggerͷجຊߏ • ϚϧνϞδϡʔϧͷجຊߏ • AnalyticsϞδϡʔϧΛྫʹɺϥΠϒϥϦͷࣝΛϞ δϡʔϧʹด͡ࠐΊΔํ๏ • ֤FeatureϞδϡʔϧͷ
• RouterϞδϡʔϧͷ
Daggerͷجຊߏ • Android Daggerͬͯ·͢ • ͨͩɺແཧͯ͠͏ඞཁͳ͍ͱࢥ͏:D • Dynamic Feature Moduleͱ૬ੑѱ͍ʢଟʣ
• ViewModelͷαϙʔτ͕ೖͬͨΒϫϯͪΌΜ (ISSUE͋Δ) • શ෦ɺDagger͔ΒΠϯελϯε࡞Ζ͏ͥʙͬͯײ͡Ͱͳ ͍ • ࣮DaggerΛͨͬΓͬͯͳ͍Ͱ͢
None
None
None
None
None
@Singleton @Component( modules = [ AndroidInjectionModule::class, FeatureModule::class, AnalyticsModule::class ] )
interface AppComponent : AndroidInjector<App> { ... }
@Singleton @Component( modules = [ AndroidInjectionModule::class, FeatureModule::class, AnalyticsModule::class ] )
interface AppComponent : AndroidInjector<App> { ... }
AnalyticsModule? • AnalyticsϞδϡʔϧʹఆٛ͞Ε͍ͯΔDaggerͷModule • Google Analytics for Firebaseʹґଘ͍ͯ͠Δ • Google
AnalyticsͱͬͬͬͯͰ͔͍ϥΠϒϥϦ • Google AnalyticsͷҰ෦ͷػೳ͔͍ͬͯ͠ͳ͍͠ɺ্ख͍͜ ͱΓ͍ͨ
interface Analytics { ... } .
interface Analytics { ... } . @Singleton internal class FirebaseAnalyticsImpl
@Inject constructor( private val app: Application ) : Analytics { ... } .
interface Analytics { ... } . @Singleton internal class FirebaseAnalyticsImpl
@Inject constructor( private val app: Application ) : Analytics { ... } .
interface Analytics { . ... } . @Singleton internal class
FirebaseAnalyticsImpl @Inject constructor( . private val app: Application ) : Analytics { . ... } .
interface Analytics { . ... . } . @Singleton internal
class FirebaseAnalyticsImpl @Inject constructor( . private val app: Application ) : Analytics { . ... . } . @Module internal interface AnalyticsBindModule { . @Binds fun bind(impl: FirebaseAnalyticsImpl): Analytics } .
interface Analytics { . ... . } . @Singleton internal
class FirebaseAnalyticsImpl @Inject constructor( . private val app: Application ) : Analytics { . ... . } . @Module internal interface AnalyticsBindModule { . @Binds fun bind(impl: FirebaseAnalyticsImpl): Analytics } .
interface Analytics { . ... . } . @Singleton .
internal class FirebaseAnalyticsImpl @Inject constructor( . private val app: Application ) : Analytics { . ... . } . @Module . internal interface AnalyticsBindModule { .. @Binds fun bind(impl: FirebaseAnalyticsImpl): Analytics } ..
@Singleton internal class FirebaseAnalyticsImpl @Inject constructor( . private val app:
Application ) : Analytics { ... . } . @Module . internal interface AnalyticsBindModule { .. @Binds fun bind(impl: FirebaseAnalyticsImpl): Analytics } .. . @Module(includes = [AnalyticsBindModule::class]) .. object AnalyticsModule { .. ... } .
@Singleton @Component( modules = [ AndroidInjectionModule::class, FeatureModule::class, AnalyticsModule::class ] )
interface AppComponent : AndroidInjector<App> { ... }
internal class GachaFragment : Fragment() { @Inject lateinit var analytics:
FirebaseAnalyticsImpl ... } .
internal class GachaFragment : Fragment() { @Inject lateinit var analytics:
Analytics ... } .
AnalyticsModule·ͱΊ • αʔυύʔςΟϥΠϒϥϦ͕ڊେ͔ͭɺͦͷࣝΛग़དྷ ΔݶΓด͡ࠐΊ͍ͨͱ͖ʹ༗ޮͳख๏ • ઐ༻ͷϞδϡʔϧΛ࡞ͬͯ͋͛ͯɺΠϯλϑΣʔεΛఆ ٛɻͦͯ͠ɺ࣮Λinternalɺ@BindsͰґଘΛఆٛ͢Δ • ·ͨϝϯς͞Ε͍ͯͳ͍ɺAPI͕ෳࡶͳࣾϥΠϒϥϦ ʹ༗ޮʹ͏͜ͱ͕ग़དྷΔ
• ϝϯς͞Εͯͳ͍ࣾϥΠϒϥϦͳΜͯͳ͍ΜͩΑͳ͊
֤FeatureϞδϡʔϧʹ͍ͭͯ • ֤FeatureϞδϡʔϧ͝ͱʹઐ༻ͷDaggerͷModuleΛ ͍࣋ͬͯΔ • gachaϞδϡʔϧ: GachaFeatureModule • settingϞδϡʔϧ: SettingFeatureModule
• …
@Module interface GachaFeatureModule { @ContributesAndroidInjector fun contributeGachaActivity(): GachaActivity }
@Module interface GachaFeatureModule { @ContributesAndroidInjector fun contributeGachaActivity(): GachaActivity } @Module(
includes = [ GachaFeatureModule::class, ] ) interface FeatureModule
@Module interface GachaFeatureModule { @ContributesAndroidInjector fun contributeGachaActivity(): GachaActivity } @Module(
includes = [ GachaFeatureModule::class, SettingFeatureModule::class, ] ) interface FeatureModule
@Module interface GachaFeatureModule { @ContributesAndroidInjector fun contributeGachaActivity(): GachaActivity } @Module(
includes = [ GachaFeatureModule::class, SettingFeatureModule::class, ShopFeatureModule::class, . ] ) interface FeatureModule
GachaFeatureModule::class, . SettingFeatureModule::class, . ShopFeatureModule::class, . ] . ) .
interface FeatureModule . @Singleton @Component( modules = [ AndroidInjectionModule::class, FeatureModule::class, AnalyticsModule::class ] ) interface AppComponent : AndroidInjector<App> { ... }
GachaFeatureModule::class, . SettingFeatureModule::class, . ShopFeatureModule::class, . ] . ) .
interface FeatureModule . @Singleton @Component( modules = [ AndroidInjectionModule::class, FeatureModule::class, AnalyticsModule::class ] ) interface AppComponent : AndroidInjector<App> { ... }
FeatureϞδϡʔϧ·ͱΊ • FeatureϞδϡʔϧຖʹɺSettingFeatureModuleΈ͍ͨ ͳײ͡ͰModuleΛఆٛ͢Δ • ଞͷΫϥεinternalͰఆٛ͢Δ͜ͱͰɺ֎ͷϞδϡʔϧ͔ ΒͷࢀরΛ࠷খݶʹ͢Δ͜ͱ͕ग़དྷΔ • ϞδϡʔϧؒͷґଘΛݮΒ͢͜ͱ͕ग़དྷΔʂ
FeatureϞδϡʔϧؒͷભҠʹ͍ͭͯ • ֤ը໘ʢFeatureʣΛαϒϞδϡʔϧʹΓग़ͨ͜͠ͱ Ͱɺ͓ޓ͍͕ࢀরग़དྷͳ͘ͳΔ • େ͖͘3ͭͷํ๏͕͋Δʢଟʣ
FeatureϞδϡʔϧؒͷભҠʹ͍ͭͯ 1 • จࣈྻʢϦϑϨΫγϣϯʣͰࢦఆ͢Δํ๏ • PlaidͰΘΕͯΔํ๏
object Activities { /** * AboutActivity */ object About :
AddressableActivity { override val className = "$PACKAGE_NAME.about.ui.AboutA ctivity" } }
FeatureϞδϡʔϧؒͷભҠʹ͍ͭͯ 2 • ֤FeatureϞδϡʔϧʹભҠ༻ͷΠϯλʔϑΣʔεΛ ఆٛͯ͠ɺappϞδϡʔϧͰ࣮͢Δ • Navigation Componentͱͷ૬ੑྑ͍ʂʂ
FeatureϞδϡʔϧؒͷભҠʹ͍ͭͯ 2 • ֤FeatureϞδϡʔϧʹભҠ༻ͷΠϯλʔϑΣʔεΛ ఆٛͯ͠ɺappϞδϡʔϧͰ࣮͢Δ • Navigation Componentͱͷ૬ੑྑ͍ʂʂ
FeatureϞδϡʔϧؒͷભҠʹ͍ͭͯ 3 • ઐ༻ͷϞδϡʔϧΛ࡞ͯ͠ɺ֤ը໘༻ͷΠϯλʔ ϑΣʔεΛఆٛ͢Δ • λοϓϧͰͦͷઐ༻ϞδϡʔϧΛRouterͰ࡞͍ͯ͠Δ • interface GachaDirections
• interface SettingDirections • ֤FeatureϞδϡʔϧͰɺ͜ͷDirectionsΠϯλʔϑΣʔ εΛ͍ભҠ͢Δ
// ͜ΕRouterϞδϡʔϧͰఆٛ interface GachaDirections { .. @CheckResult fun createIntent(context: Context):
Intent } .
// ͜ΕRouterϞδϡʔϧͰఆٛ interface GachaDirections { .. @CheckResult fun createIntent(context: Context):
Intent } . // ҎԼɺGachaϞδϡʔϧ internal class GachaDirectionsImpl @Inject constructor() : GachaDirections { . override fun createIntent(context: Context): Intent { . return GachaActivity.createIntent(context) } . } .
} . // ҎԼɺGachaϞδϡʔϧ internal class GachaDirectionsImpl @Inject constructor() :
GachaDirections { . override fun createIntent(context: Context): Intent { . return GachaActivity.createIntent(context) } . } . @Module internal interface GachaBindsModule { . @Binds fun bindGachaDirections(directions: GachaDirectionsImpl): GachaDirections } .
override fun createIntent(context: Context): Intent { . return GachaActivity.createIntent(context) }
. } . @Module internal interface GachaBindsModule { . @Binds fun bindGachaDirections(directions: GachaDirectionsImpl): GachaDirections } . @Module( includes = [ GachaBindsModule::class ] ) interface GachaFeatureModule
@Singleton @Component( modules = [ AndroidInjectionModule::class, FeatureModule::class, AnalyticsModule::class, ] )
interface AppComponent : AndroidInjector<App> { ... }
@Module( includes = [ GachaFeatureModule::class, ... ] ) interface FeatureModule
class MainActivity : AppCompatActivity() { @Inject lateinit var gachaDirections: GachaDirections
}
None
·ͱΊ • Google AnalyticsͳͲͷϥΠϒϥϦͷࣝΛด͡ࠐΊΔͨΊ ʹɺϞδϡʔϧΛఆٛ͠ɺDaggerͰґଘΛղܾ͢Δ • ϥΠϒϥϦ͕มΘΔՄೳੑ͕ߴ͍߹ɺΑΓ༗ޮ • ֤ը໘ͷભҠɺΠϯλʔϑΣʔεΛదͳϞδϡʔϧʹ ஔͯ͠ɺదͳϞδϡʔϧͰ࣮͠ɺDaggerͰґଘΛղܾ͢Δ
• λοϓϧͩͱRouterϞδϡʔϧʹΠϯλʔϑΣʔεΛஔɺ࣮ ֤FeatureϞδϡʔϧͰߦ͍ͬͯΔ