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
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
830
Introduction of accessibility for mobile development
itome
0
260
Architecture_for_mobile_development.pdf
itome
0
290
Android_Accessibility_Suite.pdf
itome
0
170
Introducing Owl
itome
0
1.2k
Featured
See All Featured
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.6k
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
The Cost Of JavaScript in 2023
addyosmani
55
10k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Typedesign – Prime Four
hannesfritz
42
3.2k
Git: the NoSQL Database
bkeepers
PRO
432
67k
Building AI with AI
inesmontani
PRO
1
1.2k
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
190
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
450
Building the Perfect Custom Keyboard
takai
2
870
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.8k
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 ௩ຊ ࢤ