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
Migrate to Koin
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
itome
December 13, 2018
360
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Migrate to Koin
itome
December 13, 2018
More Decks by itome
See All by itome
今日始め るCloudflare Browser Rendering
itome
2
340
Android accessibility and automated check tools
itome
1
5.1k
Accessibility in CATS
itome
4
2.6k
Introduce_Owl.pdf
itome
0
120
Introducing Android Accessibility Test with Accessibility Testing Framework
itome
1
800
Introduction of accessibility for mobile development
itome
0
260
Architecture_for_mobile_development.pdf
itome
0
280
Android_Accessibility_Suite.pdf
itome
0
170
Introducing Owl
itome
0
1.2k
Featured
See All Featured
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
540
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.2k
Bootstrapping a Software Product
garrettdimon
PRO
307
120k
How to Talk to Developers About Accessibility
jct
2
260
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
250
Unsuck your backbone
ammeep
672
58k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.8k
GitHub's CSS Performance
jonrohan
1033
470k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.3k
Optimising Largest Contentful Paint
csswizardry
37
3.7k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
2.9k
Transcript
Dagger͔ΒKoinʹΓ͑Δ Shibuya.apk #30
ࣗݾհ ௩ຊࢤ https://twitter.com/itometeam https://github.com/itome https://medium.com/@itometeam Cyberagent CATS 1min
Koinͱʁ 7min
Koinͱʁ 7min ɾKotlinͷܰྔDIϥΠϒϥϦ ɾno proxy, no code generation, no reflection!
ɾReady for ViewModel ɾKotlin DSLΛͬͨ؆ܿͳهड़Ͱґଘੑ͕هड़Ͱ͖Δ ɾEasy testing
Koinͱʁ ɾKotlinͷܰྔDIϥΠϒϥϦ ɾno proxy, no code generation, no reflection! ɾReady
for ViewModel ɾKotlin DSLΛͬͨ؆ܿͳهड़Ͱґଘੑ͕هड़Ͱ͖Δ ɾEasy testing 7min
Koinͱʁ ɾKotlinͷܰྔDIϥΠϒϥϦ // Add Jcenter to your repositories if needed
repositories { jcenter() } dependencies { // Koin for Android compile 'org.koin:koin-android:1.0.2' } Daggerͱಉ༷ʹAndroidݶఆϥΠϒϥϦͰͳ͍ͨΊɺ SparkKtorͳͲͷαʔόʔαΠυKotlinͰར༻Մೳ koin-androidϞδϡʔϧΛbuild.gradleʹهड़͢Δ͜ͱͰAndroidͰར༻Ͱ͖Δ υΩϡϝϯτ͕ॆ࣮͍ͯ͠ΔͷͰɺDIͷ֓೦Λཧղ͍ͯ͠Ε͙͢ʹ͍࢝ΊΒΕΔ 7min
Koinͱʁ ɾKotlinͷܰྔDIϥΠϒϥϦ ɾno proxy, no code generation, no reflection! ɾReady
for ViewModel ɾKotlin DSLΛͬͨ؆ܿͳهड़Ͱґଘੑ͕هड़Ͱ͖Δ ɾEasy testing 7min
ɾKotlin DSLΛͬͨ؆ܿͳهड़Ͱґଘੑ͕هड़Ͱ͖Δ val appModule = module { // single instance
of HelloRepository single<HelloRepository> { HelloRepositoryImpl() } // Simple Presenter Factory factory { MySimplePresenter(get()) } } moduleʹscopeؔΛهड़ͯ͠ґଘੑΛՃ͍ͯ͘͠ single: ΞϓϦέʔγϣϯͱಉ͡ϥΠϑαΠΫϧΛ࣋ͭΠϯελϯεΛ ࡞͢Δ ɻ factory: ඞཁʹͳΔͨͼʹผͷΠϯελϯεΛ࡞͢Δɻ scope: ΧελϜείʔϓΛఆٛͰ͖Δɻ Koinͱʁ 7min
ɾKotlin DSLΛͬͨ؆ܿͳهड़Ͱґଘੑ͕هड़Ͱ͖Δ val appModule = module { // single instance
of HelloRepository single<HelloRepository> { HelloRepositoryImpl() } // Simple Presenter Factory factory { MySimplePresenter(get()) } } Koinͱʁ Daggerͱҧ͍ɺґଘάϥϑʹ͋ΔܕΛConstructor Injection͢Δ͚ͩͷ߹Ͱɺ ఆٛͷίʔυΛmoduleʹॻ͔ͳͯ͘ͳΒͳ͍ ͢Ͱʹґଘੑ͕ఆٛ͞Ε͍ͯΔΫϥε get()ͰऔಘͰ͖ΔͷͰɺ Constructor Injection͢Δͱ͖Ҿͷ͚ͩget()Λॻ͚ͩ͘Ͱ͍͍ 7min
ɾKotlin DSLΛͬͨ؆ܿͳهड़Ͱґଘੑ͕هड़Ͱ͖Δ Koinͱʁ class MainApplication : Application() { override fun
onCreate() { super.onCreate() // start Koin context startKoin(this, listOf(appModule) } } ApplicationΫϥεͷonCreateͰ startKoin ʹModuleͷϦετΛ͢͜ͱͰ ґଘੑάϥϑ͕࡞͞ΕΔɻ 7min
Koinͱʁ ɾKotlinͷܰྔDIϥΠϒϥϦ ɾno proxy, no code generation, no reflection! ɾReady
for ViewModel ɾKotlin DSLΛͬͨ؆ܿͳهड़Ͱґଘੑ͕هड़Ͱ͖Δ ɾEasy testing 7min
Koinͱʁ ɾno proxy, no code generation, no reflection! Koin࣮ࡍͷґଘੑͷೖΛKotlinͷDelegateΛ࣮ͬͯݱ͍ͯ͠ΔͨΊɺDaggerͷΑ͏ͳ ίʔυੜ͕ඞཁͳ͍
val appModule = module { single<Hello> { HelloServiceImpl(get()) } } class MyActivity : AppCompatActivity(){ val presenter : MyPresenter by inject() } ؔʹΑͬͯґଘੑͷೖ͕Ͱ͖ΔͨΊɺonCreateͳͲͰ໌ࣔతʹ inject injectΛݺͿඞཁ͕ͳ͍ 7min
Koinͱʁ ɾKotlinͷܰྔDIϥΠϒϥϦ ɾno proxy, no code generation, no reflection! ɾReady
for ViewModel ɾKotlin DSLΛͬͨ؆ܿͳهड़Ͱґଘੑ͕هड़Ͱ͖Δ ɾEasy testing 7min
Koinͱʁ ɾReady for ViewModel AACͷViewModelΛσϑΥϧτͰαϙʔτ͍ͯ͠Δ class MyActivity : AppCompatActivity(){ //
Lazy inject MyViewModel val model : MyViewModel by viewModel() } ͷΘΓʹ by viewModel() by inject() Λ͏͜ͱͰ ViewModelProvider͔ΒViewModelͷΠϯελϯεΛऔಘͯ͘͠ΕΔ ಉҰͷActivityʹଐ͢ΔෳͷFragmentؒͰViewModelΛڞ༗͍ͨ͠ͱ͖ɺΘΓʹ by sharedViewModel() Λ͏ 7min
Koinͱʁ ɾKotlinͷܰྔDIϥΠϒϥϦ ɾno proxy, no code generation, no reflection! ɾReady
for ViewModel ɾKotlin DSLΛͬͨ؆ܿͳهड़Ͱґଘੑ͕هड़Ͱ͖Δ ɾEasy testing 7min
Koinͱʁ ɾEasy testing class MyTest : KoinTest { // Lazy
inject property val componentB : ComponentB by inject() @Test fun `should inject my components`() { startKoin(listOf(appModule))) // directly request an instance val componentA = get<ComponentA>() assertNotNull(a) assertEquals(componentA, componentB.a) } } KoinTestΛܧঝͨ͠ςετΫϥεͷதͰຊ൪ͱಉ༷ʹ startKoin ͕Ͱ͖Δ 7min
Koinͱʁ ɾEasy testing @Test fun `check module`() { checkModules(listOf(appModule))) }
Ϟδϡʔϧͷґଘੑ͕ղܾ͞Ε͍ͯΔ͔ͷςετͰ͖Δ 7min
Dagger → Koin 3min
Dagger → Koin 3min ɾDIͷείʔϓΛίϯτϩʔϧ͍ͨ͠ ɾநΫϥεΛೖ͍ͨ͠ ɾಉ͡ܕʹผͷΠϯελϯεΛೖ͍ͨ͠ ɾModuleΛ֊Խ͍ͨ͠
Dagger → Koin 3min ɾDIͷείʔϓΛίϯτϩʔϧ͍ͨ͠ ɾநΫϥεΛೖ͍ͨ͠ ɾಉ͡ܕʹผͷΠϯελϯεΛೖ͍ͨ͠ ɾModuleΛ֊Խ͍ͨ͠
ɾDIͷείʔϓΛίϯτϩʔϧ͍ͨ͠ 3min Dagger → Koin factory, single, scopeؔΛͬͯείʔϓΛ੍ޚ͢Δ ೖͷͨͼʹΠϯελϯε࡞ Dagger
@Provides fun provideMyPresenter(): MyPresenter = … Koin factory { MyPresenter() }
ɾDIͷείʔϓΛίϯτϩʔϧ͍ͨ͠ 3min Dagger → Koin factory, single, scopeؔΛͬͯείʔϓΛ੍ޚ͢Δ ΞϓϦέʔγϣϯ୯ҐͰڞ௨ͷΠϯελϯεΛ͏ Dagger
@Provides @Singleton fun provideRetrofit( okHttpClient: OkHttpClient ): Retrofit Koin single { Retrofit.Builder()… }
ɾDIͷείʔϓΛίϯτϩʔϧ͍ͨ͠ 3min Dagger → Koin factory, single, scopeؔΛͬͯείʔϓΛ੍ޚ͢Δ ΧελϜείʔϓΛఆٛ Dagger
@Scope @Retention(AnnotationRetention.RUNTIME) annotation class ActivityScope @Subcomponent @ActivityScope interface MyActivitySubcomponent { ... } Koin scope(“MyActivity”) { … }
Dagger → Koin 3min ɾDIͷείʔϓΛίϯτϩʔϧ͍ͨ͠ ɾநΫϥεΛೖ͍ͨ͠ ɾಉ͡ܕʹผͷΠϯελϯεΛೖ͍ͨ͠ ɾModuleΛ֊Խ͍ͨ͠
ɾModuleΛ֊Խ͍ͨ͠ 3min Dagger → Koin Dagger @Subcomponent interface MyActivitySubcomponent {…}
@Module(subcomponents = MyActivitySubcomponet::class.java) class MyActivityModule {} @Component(modules = [MyActivityModule::class.java]) interface MyActivityComponent {…} Koin module("MyActivity") { module("MyActivitySub") { … } }
Dagger → Koin 3min ɾDIͷείʔϓΛίϯτϩʔϧ͍ͨ͠ ɾநΫϥεΛೖ͍ͨ͠ ɾಉ͡ܕʹผͷΠϯελϯεΛೖ͍ͨ͠ ɾModuleΛ֊Խ͍ͨ͠
ɾநΫϥεΛೖ͍ͨ͠ 3min Dagger → Koin Dagger @Binds fun bindUserApi( userApiClient:
UserApiClient ): UserApi Koin single { UserApiClient() } bind UserApi::class
Dagger → Koin 3min ɾDIͷείʔϓΛίϯτϩʔϧ͍ͨ͠ ɾநΫϥεΛೖ͍ͨ͠ ɾಉ͡ܕʹผͷΠϯελϯεΛೖ͍ͨ͠ ɾModuleΛ֊Խ͍ͨ͠
ɾಉ͡ܕʹผͷΠϯελϯεΛೖ͍ͨ͠ 3min Dagger → Koin Dagger @Provides @Named("debug-client") fun provideDebugApiClient(retrofit:
Retrofit): ApiClient @Provides @Named("prod-client") fun provideProdApiClient(retrofit: Retrofit): ApiClient Koin single("debug-client") { ApiClient() } single("prod-client") { ApiClient() }
ϝϦοτɾσϝϦοτ 3min
ɾϝϦοτ 3min ϝϦοτɾσϝϦοτ Daggerʹൺͯґଘੑͷهड़ํ๏͕؆ܿͰɺΘ͔Γ͍͢ Field InjectionͷͨΊʹมΛpublicʹ͢Δඞཁ͕ͳ͍ AACͷViewModelͷInjectionʹରԠ͍ͯ͠Δ ίʔυੜΛߦΘͳ͍ͷͰɺίϯύΠϧ࣌ؒॖ͕ݟࠐΊΔ ϚϧνϞδϡʔϧϓϩδΣΫτͷಋೖ͕؆୯
ɾσϝϦοτ 3min ϝϦοτɾσϝϦοτ ґଘੑͷղܾΛίϯύΠϧ࣌ʹ͢ΔDaggerʹൺͯϥϯλΠϜ͕͍ ґଘੑͷॆʹࣦഊͨ͠ͱ͖ʹϥϯλΠϜΤϥʔͰམͪΔ͜ͱ͕͋Δ →ґଘੑͷॆʹ͍ͭͯςετ͕Ͱ͖ΔͨΊɺ൛Ͱى͜Δ֬Լ͛ΒΕΔ https://github.com/Sloy/android-dependency-injection-performance → moduleఆٛʹcreateOnStart=falseΛ͢͜ͱͰΠϯελϯεԽΛԆͰ͖Δ
·ͱΊ 1min
͋Γ͕ͱ͏͍͟͝·ͨ͠ Shibuya.apk #30 https://twitter.com/itometeam https://github.com/itome https://medium.com/@itometeam Cyberagent CATS ௩ຊ ࢤ