SlideShare ist ein Scribd-Unternehmen logo
1 von 91
Downloaden Sie, um offline zu lesen
Using Hilt in a
modularized project
Fabio Collini
@fabioCollini
Dependency Injection
Vs
Service Locator
class MyClass {

private val collaborator2 = Collaborator2()

fun execute() {

val value = Collaborator1.loadSomething()

collaborator2.doSomethingElse(value)

}

}
Plaincode
class MyClass(serviceLocator: ServiceLocator) {

private val collaborator1 = serviceLocator.collaborator1

private val collaborator2 = serviceLocator.collaborator2

fun execute() {

val value = collaborator1.loadSomething()

collaborator2.doSomethingElse(value)

}

}
ServiceLocator
class MyClass(

private val collaborator1: Collaborator1,

private val collaborator2: Collaborator2

) {

fun execute() {

val value = collaborator1.loadSomething()

collaborator2.doSomethingElse(value)

}

}
DependencyInjection
class MyClass(

private val collaborator1: Collaborator1,

private val collaborator2: Collaborator2

) {

fun execute() {

val value = collaborator1.loadSomething()

collaborator2.doSomethingElse(value)

}

}
class MyClass(serviceLocator: ServiceLocator) {

private val collaborator1 = serviceLocator.collaborator1

private val collaborator2 = serviceLocator.collaborator2

fun execute() {

val value = collaborator1.loadSomething()

collaborator2.doSomethingElse(value)

}

}
ServiceLocatorDependencyInjection
Dependencies are
retrieved using the
Service Locator
Dependencies are
injected by the
container
Dagger is a Dependency Injection framework
But a Dagger component can be used as a Service Locator
Is Dagger a Dependency Injection framework?
What about Hilt?
WhatIcareabout
Dependency Injection on classes we can instantiate
Easy setup on classes instantiated by the framework
Testability
Objects
definition
Dagger&Hilt
The same syntax can be
used to define objects using
both Dagger and Hilt
class MyRepository(

private val api: Api

) {

fun loadData() = api.load()

}
class MyRepository @Inject constructor(

private val api: Api

) {

fun loadData() = api.load()

}
@Singleton

class MyRepository @Inject constructor(

private val api: Api

) {

fun loadData() = api.load()

}
Retrofit.Builder()

.baseUrl("""...")

!//!!...

.build()

.create(Api"::class.java)
@Provides

@Singleton

fun provideApi(): Api {

return Retrofit.Builder()

.baseUrl("""...")

!//!!...

.build()

.create(Api"::class.java)

}
@Module

object MyModule {

@Provides

@Singleton

fun provideApi(): Api {

return Retrofit.Builder()

.baseUrl("""...")

!//!!...

.build()

.create(Api"::class.java)

}

}
Using an object
instead of a class
Dagger generates
less code
@Singleton

class MyRepository @Inject constructor(

private val api: Api

) {

fun loadData() = api.load()

}
@Singleton

class MyRepository @Inject constructor(

private val cache: Cache,

private val api: Api

) {

fun loadData() = cache.load() "?: api.load()

}
interface MyRepository {

fun loadData(): Any

}

@Singleton

class MyRepositoryImpl @Inject constructor(

private val cache: Cache,

private val api: Api

) : MyRepository {

override fun loadData() = cache.load() "?: api.load()

}1
interface MyRepository {

fun loadData(): Any

}

@Singleton

class MyRepositoryImpl @Inject constructor(

private val cache: Cache,

private val api: Api

) : MyRepository {

override fun loadData() = cache.load() "?: api.load()

}1

@Module

interface AnotherModule {

@Binds

fun MyRepositoryImpl.bindsRepository(): MyRepository

}
Hilt
@InstallIn

@AndroidEntryPoint

@ViewModelInject

@HiltAndroidApp

@EntryPoint
Newannotations
@Module

object MyModule {

!//!!...

}
@Module

@InstallIn(SingletonComponent"::class)

object MyModule {

!//!!...

}
@Module

@InstallIn(SingletonComponent"::class)

object OkHttpConfigModule {

@Provides

@ElementsIntoSet

fun provideDefaultInterceptors(): Set<Interceptor> = emptySet()

@Singleton

@Provides

fun providesOkHttpClient(

interceptors: @JvmSuppressWildcards Set<Interceptor>

): OkHttpClient {

val httpClient = OkHttpClient.Builder()

interceptors.forEach {

httpClient.addInterceptor(it)

}

return httpClient.build()

}1

}2
src/main
@Module

@InstallIn(SingletonComponent"::class)

object OkHttpConfigModule {

@Provides

@ElementsIntoSet

fun provideDefaultInterceptors(): Set<Interceptor> = emptySet()

@Singleton

@Provides

fun providesOkHttpClient(

interceptors: @JvmSuppressWildcards Set<Interceptor>

): OkHttpClient {

val httpClient = OkHttpClient.Builder()

interceptors.forEach {

httpClient.addInterceptor(it)

}

return httpClient.build()

}1

}2

@Module

@InstallIn(SingletonComponent"::class)

object DebugOkHttpConfigModule {

@Provides

@IntoSet

fun provideDebugInterceptor(): Interceptor = HttpLoggingInterceptor()

}
src/mainsrc/debug
class MainActivity : AppCompatActivity() {

@Inject

lateinit var permissionManager: PermissionManager

@Inject

lateinit var mainNavigator: MainNavigator

!//!!...

}
@AndroidEntryPoint

class MainActivity : AppCompatActivity() {

@Inject

lateinit var permissionManager: PermissionManager

@Inject

lateinit var mainNavigator: MainNavigator

!//!!...

}
@AndroidEntryPoint

class MainActivity : AppCompatActivity() {

@Inject

lateinit var permissionManager: PermissionManager

@Inject

lateinit var mainNavigator: MainNavigator

!//!!...

}
@AndroidEntryPoint

class MainActivity : AppCompatActivity() {

private val viewModel: MyViewModel by viewModels()

@Inject

lateinit var permissionManager: PermissionManager

@Inject

lateinit var mainNavigator: MainNavigator

!//!!...

}
class MyViewModel @ViewModelInject constructor(

private val useCase: MyUseCase

) : ViewModel() {

!//!!...

}
class MyViewModel @ViewModelInject constructor(

private val useCase: MyUseCase,

@Assisted private val handle: SavedStateHandle

) : ViewModel() {

!//!!...

}
class MyViewModel @ViewModelInject constructor(

private val useCase: MyUseCase,

@Assisted private val handle: SavedStateHandle

) : ViewModel() {

init {

load(handle.get<String>("Id"))

}

!//!!...

}
class MyApp : Application() {

@Inject

lateinit var dependency: Dependency

!//!!...

}
@HiltAndroidApp

class MyApp : Application() {

@Inject

lateinit var dependency: Dependency

!//!!...

}
No more components!
(sort of…)
@Component(

modules = {

"//""...

}

)

@Singleton

public abstract static class SingletonC implements SingletonComponent,

"//…

{

}

@Subcomponent(

modules = {

"//""...

}

)

@ActivityScoped

public abstract static class ActivityC implements ActivityComponent,

"//""...

{

@Subcomponent.Builder

abstract interface Builder extends ActivityComponentBuilder {

}

}
!!/**

* A generated base class to be extended by the @dagger.hilt.android.AndroidEntryPoint annotated class.

* If using the Gradle plugin, this is swapped as the base class via bytecode transformation.

!*/

public abstract class Hilt_MainActivity extends AppCompatActivity

implements GeneratedComponentManagerHolder {

"//""...

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

((MainActivity_GeneratedInjector) this.generatedComponent())

.injectMainActivity(UnsafeCasts.<MainActivity>unsafeCast(this));

super.onCreate(savedInstanceState);

}

"//""...

}
!!/**

* A generated base class to be extended by the @dagger.hilt.android.AndroidEntryPoint annotated class.

* If using the Gradle plugin, this is swapped as the base class via bytecode transformation.

!*/

public abstract class Hilt_MainActivity extends AppCompatActivity

implements GeneratedComponentManagerHolder {

"//""...

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

((MainActivity_GeneratedInjector) this.generatedComponent())

.injectMainActivity(UnsafeCasts.<MainActivity>unsafeCast(this));

super.onCreate(savedInstanceState);

}

"//""...

}
!!/**

* A generated base class to be extended by the @dagger.hilt.android.AndroidEntryPoint annotated class.

* If using the Gradle plugin, this is swapped as the base class via bytecode transformation.

!*/

public abstract class Hilt_MainActivity extends AppCompatActivity

implements GeneratedComponentManagerHolder {

"//""...

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

((MainActivity_GeneratedInjector) this.generatedComponent())

.injectMainActivity(UnsafeCasts.<MainActivity>unsafeCast(this));

super.onCreate(savedInstanceState);

}

"//""...

}
MonolithicComponent
Simple
sometimes you need an extra Qualifier annotation
Less generated code
Everything can be injected everywhere
internal can be useful to limit the scope
@EntryPoint

@InstallIn(SingletonComponent"::class)

interface MyEntryPoint {

val myUseCase: MyUseCase



fun inject(something: Something)

}
@EntryPoint

@InstallIn(SingletonComponent"::class)

interface MyEntryPoint {

val myUseCase: MyUseCase



fun inject(something: Something)

}

val entryPoint = EntryPointAccessors.fromApplication(

app, MyEntryPoint"::class.java)

val useCase = entryPoint.myUseCase
Testing
class MyClass @Inject constructor(

private val collaborator1: Collaborator1,

private val collaborator2: Collaborator2

) {

fun execute() {

val value = collaborator1.loadSomething()

collaborator2.doSomethingElse(value)

}

}
class MyClassTest {

private val collaborator1 = mock<Collaborator1>()

private val collaborator2 = mock<Collaborator2>()

private val myObject = MyClass(collaborator1, collaborator2)

@Test

fun testSomething() {

whenever(collaborator1.loadSomething()) doReturn "something"

myObject.execute()

verify(collaborator2).doSomethingElse("something")

}

}
@Singleton

open class MyAnalytics @Inject constructor()

interface MyUseCase

@Singleton

class MyUseCaseImpl @Inject constructor() : MyUseCase

@Module

@InstallIn(SingletonComponent"::class)

interface MyModule {

@Binds

fun MyUseCaseImpl.bindsUseCase(): MyUseCase

}

@AndroidEntryPoint

class MyActivity : AppCompatActivity() {

@Inject

lateinit var analytics: MyAnalytics

@Inject

lateinit var useCase: MyUseCase

!//!!...

}
@HiltAndroidTest

class MyActivityTest {

@get:Rule1

val hiltRule = HiltAndroidRule(this)

@get:Rule

val rule = ActivityTestRule(MyActivity"::class.java, false, false)

}
@HiltAndroidTest

class MyActivityTest {

@get:Rule1

val hiltRule = HiltAndroidRule(this)

@get:Rule

val rule = ActivityTestRule(MyActivity"::class.java, false, false)

@Inject

lateinit var analytics: MyAnalytics

@Inject

lateinit var useCase: MyUseCase

@Test

fun startActivity() {

rule.launchActivity(null)

hiltRule.inject()

!//now the properties contain the production objects

}

}
@HiltAndroidTest

class MyActivityTest {

@get:Rule1

val hiltRule = HiltAndroidRule(this)

@get:Rule

val rule = ActivityTestRule(MyActivity"::class.java, false, false)

@Test

fun startActivity() {

rule.launchActivity(null)

!//!!...

}

}
@Module

@InstallIn(SingletonComponent"::class)

object FakeAnalyticsModule {

@Provides

fun provideAnalytics(): MyAnalytics = mock()

}

@HiltAndroidTest

class MyActivityTest {

@get:Rule1

val hiltRule = HiltAndroidRule(this)

@get:Rule

val rule = ActivityTestRule(MyActivity"::class.java, false, false)

@Test

fun startActivity() {

rule.launchActivity(null)

!//!!...

}

}
@HiltAndroidTest

class MyActivityTest {

@get:Rule1

val hiltRule = HiltAndroidRule(this)

@get:Rule

val rule = ActivityTestRule(MyActivity"::class.java, false, false)

@Module

@InstallIn(SingletonComponent"::class)

object FakeAnalyticsModule {

@Provides

fun provideAnalytics(): MyAnalytics = mock()

}

@Test

fun startActivity() {

rule.launchActivity(null)

!//!!...

}

}
@HiltAndroidTest

class MyActivityTest {

@get:Rule

val hiltRule = HiltAndroidRule(this)

@get:Rule

val rule = ActivityTestRule(MyActivity"::class.java, false, false)

@BindValue

@JvmField

val analytics: MyAnalytics = mock()

@Test

fun startActivity() {

rule.launchActivity(null)

!//!!...

}

}
@HiltAndroidTest

class MyActivityTest {

@get:Rule

val hiltRule = HiltAndroidRule(this)

@get:Rule

val rule = ActivityTestRule(MyActivity"::class.java, false, false)

@BindValue

@JvmField

val useCase: MyUseCase = mock()

@Test

fun startActivity() {

rule.launchActivity(null)

!//!!...

}

}
error: [Dagger/DuplicateBindings] MyUseCase is bound multiple times
@HiltAndroidTest

@UninstallModules(MyModule"::class)

class MyActivityTest {

@get:Rule

val hiltRule = HiltAndroidRule(this)

@get:Rule

val rule = ActivityTestRule(MyActivity"::class.java, false, false)

@BindValue

@JvmField

val useCase: MyUseCase = mock()

@Test

fun startActivity() {

rule.launchActivity(null)

!//!!...

}

}
Multi-module
architecture
It works!
feature3feature1 feature2
App
feature3feature1 feature2
AppFeature1App
feature1 feature2
Feature1App
feature3
App
Activity
Repository
Api
UseCase
ViewModel
entitiesentitiesentitiesentities
domain
repository
UI
data source
presenter
Activity
Repository
Api
UseCase
ViewModel
entitiesentitiesentitiesentities
domain
repository
UI
data source
presenter
Activity
Repository
Api
UseCase
ViewModel
RepositoryImplRepositoryUseCase
domain data
UseCase
RepositoryImpl
Repository
domain data
Repository RepositoryImpl
UseCase
Inversion
Of Control
The “I” in S.O.L.I.D.
https://www.youtube.com/watch?v=GlDsfq3xHvo&t=
domain repository
Repository RepositoryImpl
UseCase
@Inject
@Inject
Module
@Binds
Incomplete Hilt config
dynamic
feature3
App
feature1 feature2
@EntryPoint
@Component
Wrappingup
Dependency Injection on classes we can instantiate
@Inject, @Provides and @Binds

Easy setup on classes instantiated by the framework
@AndroidEntryPoint and @HiltAndroidApp
Testability
@HiltAndroidTest and HiltAndroidRule
Hilt is definitely a
Dependency Injection framework
Hilt is definitely a
Dependency Injection framework
(even if you can use an EntryPoint as a Service Locator)
Links&contacts
Hilt documentation
dagger.dev/hilt/
Android Developers - Dependency injection with Hilt
developer.android.com/training/dependency-injection/hilt-android
Android Developers - Hilt testing guide
developer.android.com/training/dependency-injection/hilt-testing
Manuel Vivo - Dagger and Hilt navigation support in Android Studio
medium.com/androiddevelopers/dagger-navigation-support-in-android-studio-49aa5d149ec9
Fabio Collini - Dagger dependencies beyond the basics
proandroiddev.com/dagger-dependencies-beyond-the-basics-53474e48f932
@fabioCollini
linkedin.com/in/fabiocollini
github.com/fabioCollini
medium.com/@fabioCollini
THANKS
FOR YOUR
ATTENTION
QUESTIONS?
@fabioCollini

Weitere ähnliche Inhalte

Was ist angesagt?

Was ist angesagt? (20)

Java Spring framework, Dependency Injection, DI, IoC, Inversion of Control
Java Spring framework, Dependency Injection, DI, IoC, Inversion of ControlJava Spring framework, Dependency Injection, DI, IoC, Inversion of Control
Java Spring framework, Dependency Injection, DI, IoC, Inversion of Control
 
Functional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorldFunctional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorld
 
Introduction to kotlin for android app development gdg ahmedabad dev fest 2017
Introduction to kotlin for android app development   gdg ahmedabad dev fest 2017Introduction to kotlin for android app development   gdg ahmedabad dev fest 2017
Introduction to kotlin for android app development gdg ahmedabad dev fest 2017
 
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass Slides
 
SOLID
SOLIDSOLID
SOLID
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Introduction to ReactJS
Introduction to ReactJSIntroduction to ReactJS
Introduction to ReactJS
 
SOLID Design Principles applied in Java
SOLID Design Principles applied in JavaSOLID Design Principles applied in Java
SOLID Design Principles applied in Java
 
Introduction to GraphQL
Introduction to GraphQLIntroduction to GraphQL
Introduction to GraphQL
 
Spring Framework - AOP
Spring Framework - AOPSpring Framework - AOP
Spring Framework - AOP
 
Angular modules in depth
Angular modules in depthAngular modules in depth
Angular modules in depth
 
RxJS Evolved
RxJS EvolvedRxJS Evolved
RxJS Evolved
 
Testing with JUnit 5 and Spring
Testing with JUnit 5 and SpringTesting with JUnit 5 and Spring
Testing with JUnit 5 and Spring
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Dependency Injection with Dagger 2 presentation
Dependency Injection with Dagger 2 presentationDependency Injection with Dagger 2 presentation
Dependency Injection with Dagger 2 presentation
 
Introduction to flutter's basic concepts
Introduction to flutter's basic conceptsIntroduction to flutter's basic concepts
Introduction to flutter's basic concepts
 
Introduction to Spring WebFlux #jsug #sf_a1
Introduction to Spring WebFlux #jsug #sf_a1Introduction to Spring WebFlux #jsug #sf_a1
Introduction to Spring WebFlux #jsug #sf_a1
 
Basics of reflection in java
Basics of reflection in javaBasics of reflection in java
Basics of reflection in java
 
Gradle Introduction
Gradle IntroductionGradle Introduction
Gradle Introduction
 

Ähnlich wie Using hilt in a modularized project

Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
Alexey Buzdin
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
C.T.Co
 

Ähnlich wie Using hilt in a modularized project (20)

Sharper Better Faster Dagger ‡ - Droidcon SF
Sharper Better Faster Dagger ‡ - Droidcon SFSharper Better Faster Dagger ‡ - Droidcon SF
Sharper Better Faster Dagger ‡ - Droidcon SF
 
Hilt Annotations
Hilt AnnotationsHilt Annotations
Hilt Annotations
 
Maintaining a dependency graph with weaver
Maintaining a dependency graph with weaverMaintaining a dependency graph with weaver
Maintaining a dependency graph with weaver
 
Dependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony ContainerDependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony Container
 
Kotlin for Android - Vali Iorgu - mRready
Kotlin for Android - Vali Iorgu - mRreadyKotlin for Android - Vali Iorgu - mRready
Kotlin for Android - Vali Iorgu - mRready
 
Android architecture
Android architecture Android architecture
Android architecture
 
Di code steps
Di code stepsDi code steps
Di code steps
 
Android & Kotlin - The code awakens #01
Android & Kotlin - The code awakens #01Android & Kotlin - The code awakens #01
Android & Kotlin - The code awakens #01
 
Dependency Injection for Android
Dependency Injection for AndroidDependency Injection for Android
Dependency Injection for Android
 
Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014
Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014
Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014
 
Dagger 2 vs koin
Dagger 2 vs koinDagger 2 vs koin
Dagger 2 vs koin
 
Architecting your GWT applications with GWT-Platform - Lesson 02
Architecting your GWT applications with GWT-Platform - Lesson 02Architecting your GWT applications with GWT-Platform - Lesson 02
Architecting your GWT applications with GWT-Platform - Lesson 02
 
Why Spring <3 Kotlin
Why Spring <3 KotlinWhy Spring <3 Kotlin
Why Spring <3 Kotlin
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
Android workshop
Android workshopAndroid workshop
Android workshop
 
Dicoding Developer Coaching #30: Android | Mengenal Macam-Macam Software Desi...
Dicoding Developer Coaching #30: Android | Mengenal Macam-Macam Software Desi...Dicoding Developer Coaching #30: Android | Mengenal Macam-Macam Software Desi...
Dicoding Developer Coaching #30: Android | Mengenal Macam-Macam Software Desi...
 
Mastering the Sling Rewriter by Justin Edelson
Mastering the Sling Rewriter by Justin EdelsonMastering the Sling Rewriter by Justin Edelson
Mastering the Sling Rewriter by Justin Edelson
 
Mastering the Sling Rewriter
Mastering the Sling RewriterMastering the Sling Rewriter
Mastering the Sling Rewriter
 
Say bye to Fragments with Conductor & Kotlin
Say bye to Fragments with Conductor & KotlinSay bye to Fragments with Conductor & Kotlin
Say bye to Fragments with Conductor & Kotlin
 

Mehr von Fabio Collini

Mehr von Fabio Collini (20)

Architectures in the compose world
Architectures in the compose worldArchitectures in the compose world
Architectures in the compose world
 
Managing parallelism using coroutines
Managing parallelism using coroutinesManaging parallelism using coroutines
Managing parallelism using coroutines
 
Kotlin Delegates in practice - Kotlin community conf
Kotlin Delegates in practice - Kotlin community confKotlin Delegates in practice - Kotlin community conf
Kotlin Delegates in practice - Kotlin community conf
 
Kotlin delegates in practice - Kotlin Everywhere Stockholm
Kotlin delegates in practice - Kotlin Everywhere StockholmKotlin delegates in practice - Kotlin Everywhere Stockholm
Kotlin delegates in practice - Kotlin Everywhere Stockholm
 
Using Dagger in a Clean Architecture project
Using Dagger in a Clean Architecture projectUsing Dagger in a Clean Architecture project
Using Dagger in a Clean Architecture project
 
Solid principles in practice the clean architecture - Droidcon Italy
Solid principles in practice the clean architecture - Droidcon ItalySolid principles in practice the clean architecture - Droidcon Italy
Solid principles in practice the clean architecture - Droidcon Italy
 
SOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
SOLID principles in practice: the Clean Architecture - Devfest Emila RomagnaSOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
SOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
 
SOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean ArchitectureSOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean Architecture
 
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFrom Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
 
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night TurinAsync code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
 
Recap Google I/O 2018
Recap Google I/O 2018Recap Google I/O 2018
Recap Google I/O 2018
 
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italyFrom java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
 
From java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+kFrom java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+k
 
Testing Android apps based on Dagger and RxJava Droidcon UK
Testing Android apps based on Dagger and RxJava Droidcon UKTesting Android apps based on Dagger and RxJava Droidcon UK
Testing Android apps based on Dagger and RxJava Droidcon UK
 
Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2
 
Testing Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJavaTesting Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJava
 
Android Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUKAndroid Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUK
 
Data Binding in Action using MVVM pattern
Data Binding in Action using MVVM patternData Binding in Action using MVVM pattern
Data Binding in Action using MVVM pattern
 
Android Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG FirenzeAndroid Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG Firenze
 
Testable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVMTestable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVM
 

Kürzlich hochgeladen

CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
VishalKumarJha10
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
shinachiaurasa2
 

Kürzlich hochgeladen (20)

Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedSector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 

Using hilt in a modularized project