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
itome
December 13, 2018
370
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
360
Android accessibility and automated check tools
itome
1
5.1k
Accessibility in CATS
itome
4
2.6k
Introduce_Owl.pdf
itome
0
130
Introducing Android Accessibility Test with Accessibility Testing Framework
itome
1
820
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
Mind Mapping
helmedeiros
PRO
1
340
The SEO Collaboration Effect
kristinabergwall1
1
550
Building a Scalable Design System with Sketch
lauravandoore
463
34k
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
310
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.9k
The Limits of Empathy - UXLibs8
cassininazir
1
630
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
250
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.5k
First, design no harm
axbom
PRO
2
1.3k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
560
How to make the Groovebox
asonas
2
2.4k
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 ௩ຊ ࢤ