Android Hilt-1
Android Hilt-1
with Hilt
Arbaz Pirwani
@arbazpirwani
@arbazpirwani
What’s a dependency
Dependency
Engine
Car
Dependency Injection (DI)
● Dependencies are provided to a class instead of the class creating them itself
Engine
Engine
Car
Without DI
class Car {
private val engine: Engine = Engine()
}
Engine
Car
With DI
class Car(private val engine: Engine) {
Engine
Car
You should ALWAYS
apply DI principles
to your app!
Importance of DI
● Reusability of code
Reuse Car
fun main(args: Array<String>){
...
}
Importance of DI
● Reusability of code
● Reusability of code
● Ease of refactoring
class Car {
}
class Car(
private val engine: Engine
) {
}
class Car(
private val engine: Engine,
private val battery: Battery,
private val airFilter: AirFilter,
private val radiator: Radiator,
private val wipers: List<Wiper>,
...
) {
// Small source code
}
Engine Radiator
Car
Car
Battery Wiper
DI benefits
● Reusability of code
● Ease of refactoring
○ Smaller - focused classes
● Ease of testing
Ease of Testing
class CarTest {
@Test
fun `Car happy path`() {
val car = Car(FakeEngine())
...
}
}
Ease of Testing
class CarTest {
@Test
fun `Car happy path`() {
val car = Car(FakeEngine())
...
}
@Test
fun `Car with failing Engine`() {
val car = Car(FakeFailingEngine())
...
}
}
Choosing the right tool
Manual DI
Tool to Use Service Locator Hilt/Dagger Hilt/Dagger
Hilt/Dagger
Manual DI
● Boilerplate
● Error-prone
iosched’s FeedViewModel
class FeedViewModel (
private val loadCurrentMomentUseCase: LoadCurrentMomentUseCase,
loadAnnouncementsUseCase: LoadAnnouncementsUseCase,
private val loadStarredAndReservedSessionsUseCase:
LoadStarredAndReservedSessionsUseCase,
getTimeZoneUseCase: GetTimeZoneUseCase,
getConferenceStateUseCase: GetConferenceStateUseCase,
private val timeProvider: TimeProvider,
private val analyticsHelper: AnalyticsHelper,
private val signInViewModelDelegate: SignInViewModelDelegate,
themedActivityDelegate: ThemedActivityDelegate,
private val snackbarMessageManager: SnackbarMessageManager
): ViewModel(),
FeedEventListener,
ThemedActivityDelegate by themedActivityDelegate,
SignInViewModelDelegate by signInViewModelDelegate {
}
https://github.com/google/iosched
Manual DI
Service Locator
Cost
Dagger
Hilt
App Size
Use Hilt!
Hilt
● Google use it internally
● We use it internally
○ Activity
○ Service
○ Broadcast Receiver
● OS will create those for you
● You don’t own those constructor
What about Dagger?
● Hard to configure
● Opinionated
● Easy to setup
● Tooling Support
● Jetpack Extension
Quick start guide
@HiltAndroidApp
class MyAndroidApp : Application()
@AndroidEntryPoint
class LoginActivity : AppCompatActivity() { /* ... */}
Quick start guide
@AndroidEntryPoint
class HomeActivity : AppCompatActivity() {
}
Annotations recap
● @Inject
● @AndroidEntryPoint
● @HiltAndroidApp
Bindings
● ViewModel
● Navigation
● Compose
● WorkManager
iosched’s FeedViewModel
@HiltViewModel
class FeedViewModel @Inject constructor(
private val loadCurrentMomentUseCase: LoadCurrentMomentUseCase,
loadAnnouncementsUseCase: LoadAnnouncementsUseCase,
private val loadStarredAndReservedSessionsUseCase:
LoadStarredAndReservedSessionsUseCase,
getTimeZoneUseCase: GetTimeZoneUseCase,
getConferenceStateUseCase: GetConferenceStateUseCase,
private val timeProvider: TimeProvider,
private val analyticsHelper: AnalyticsHelper,
private val signInViewModelDelegate: SignInViewModelDelegate,
themedActivityDelegate: ThemedActivityDelegate,
private val snackbarMessageManager: SnackbarMessageManager
): ViewModel(),
FeedEventListener,
ThemedActivityDelegate by themedActivityDelegate,
SignInViewModelDelegate by signInViewModelDelegate {
}
https://github.com/google/iosched
iosched’s FeedFragment
@AndroidEntryPoint
class FeedFragment : MainNavigationFragment() {
● Migration guide:
○ dagger.dev/hilt/migration-guide
goo.gle/hilt-cheatsheet
Takeaways
● Use Hilt