Dependency Injection con Hilt
Semplifichi la gestione delle dipendenze con Hilt. Usi @HiltAndroidApp, @AndroidEntryPoint, @HiltViewModel, @Module, @Provides e gli scope @Singleton.
Dependency Injection con Hilt è una lezione Android Academy gratuita su CoddyKit. Questa è la lezione 6 di 6. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Android Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Android Academy include 6 lezioni in totale.
Che cos'è la Dependency Injection?
Dependency Injection (DI) significa fornire a un oggetto ciò di cui ha bisogno, invece di fargli creare autonomamente le proprie dipendenze.
Senza DI, una classe crea le proprie dipendenze: il codice è strettamente accoppiato e difficile da testare. Con DI, le dipendenze vengono iniettate dall'esterno: il codice è debolmente accoppiato, facile da testare e da sostituire.
DI manuale e Hilt
La DI manuale funziona, ma su larga scala diventa complicata:
// Manual DI — you create and pass everything:
val db = AppDatabase.getInstance(context)
val dao = db.userDao()
val repo = UserRepository(dao)
val factory = UserViewModel.Factory(repo)
val viewModel = ViewModelProvider(this, factory)[UserViewModel::class.java]
// With Hilt:
// Just annotate, Hilt does the wiring
@HiltViewModel
class UserViewModel @Inject constructor(private val repo: UserRepository) : ViewModel()Aggiunta di Hilt
Aggiunga Hilt al progetto:
// project/build.gradle:
buildscript {
dependencies {
classpath 'com.google.dagger:hilt-android-gradle-plugin:2.51'
}
}
// app/build.gradle:
plugins {
id 'com.google.dagger.hilt.android'
id 'kotlin-kapt'
}
dependencies {
implementation 'com.google.dagger:hilt-android:2.51'
kapt 'com.google.dagger:hilt-android-compiler:2.51'
}@HiltAndroidApp
Annoti la classe Application con @HiltAndroidApp. Questo è il punto di ingresso per la gerarchia dei componenti Hilt:
@HiltAndroidApp
class MyApp : Application()
// Also register in AndroidManifest.xml:
// <application android:name=".MyApp" ...>@AndroidEntryPoint
Aggiunga @AndroidEntryPoint alle Activity, ai Fragment e ai Service che richiedono dipendenze iniettate:
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject lateinit var analytics: AnalyticsService
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
analytics.logEvent("app_open")
}
}
@AndroidEntryPoint
class HomeFragment : Fragment() {
// Fragment's parent Activity must also be @AndroidEntryPoint
}@Inject — injection tramite costruttore
Contrassegni il costruttore con @Inject per indicare a Hilt come creare la classe. Hilt risolve automaticamente tutti i parametri:
class UserRepository @Inject constructor(
private val userDao: UserDao,
private val apiService: ApiService
) {
suspend fun getUsers() = userDao.getAll()
suspend fun syncFromNetwork() {
val users = apiService.fetchUsers()
userDao.insertAll(users)
}
}
// Hilt sees UserRepository needs UserDao and ApiService,
// and automatically creates and injects them.@HiltViewModel
Annoti il ViewModel con @HiltViewModel e usi @Inject constructor. Nel Fragment, lo recuperi con by viewModels():
@HiltViewModel
class UserViewModel @Inject constructor(
private val repo: UserRepository
) : ViewModel() {
val users = repo.getUsersFlow().asLiveData()
}
// In Fragment:
@AndroidEntryPoint
class UserFragment : Fragment() {
private val viewModel: UserViewModel by viewModels() // Hilt provides it
}@Module e @Provides
Quando Hilt non può usare l'injection tramite costruttore (ad esempio per interfacce o classi di terze parti), fornisca le istanze tramite un @Module:
@Module
@InstallIn(SingletonComponent::class) // lives for app lifetime
object NetworkModule {
@Provides
@Singleton
fun provideRetrofit(): Retrofit {
return Retrofit.Builder()
.baseUrl("https://api.example.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
}
@Provides
@Singleton
fun provideApiService(retrofit: Retrofit): ApiService {
return retrofit.create(ApiService::class.java)
}
}@Binds — binding delle interfacce
Usi @Binds per indicare a Hilt quale implementazione utilizzare per un'interfaccia:
interface AnalyticsService {
fun logEvent(name: String)
}
class FirebaseAnalytics @Inject constructor() : AnalyticsService {
override fun logEvent(name: String) { /* Firebase impl */ }
}
@Module
@InstallIn(SingletonComponent::class)
abstract class AnalyticsModule {
@Binds
@Singleton
abstract fun bindAnalytics(impl: FirebaseAnalytics): AnalyticsService
}Scope di Hilt
Gli scope controllano per quanto tempo vive un'istanza iniettata:
@Singleton— una sola istanza per tutta la durata dell'app (ApplicationComponent)@ActivityRetainedScoped— sopravvive alle modifiche di configurazione@ActivityScoped— una sola istanza per Activity@FragmentScoped— una sola istanza per Fragment@ViewModelScoped— una sola istanza per ViewModel
Test con Hilt
Sostituisca le dipendenze reali con oggetti fittizi nei test usando il supporto di Hilt per i test:
@HiltAndroidTest
class UserRepositoryTest {
@get:Rule
val hiltRule = HiltAndroidRule(this)
@Inject
lateinit var repo: UserRepository
@Before
fun setUp() {
hiltRule.inject()
}
@Test
fun usersAreFetched() {
assertNotNull(repo)
}
}Verifica rapida
Quale annotazione indica a Hilt di generare la gerarchia dei componenti DI per l'intera applicazione?
Riepilogo: Dependency Injection con Hilt
Hilt rende quasi automatica la DI in Android:
@HiltAndroidAppsulla classe Application@AndroidEntryPointsu Activity e Fragment@Inject constructorper le classi iniettabili@HiltViewModel+@Inject constructorper i ViewModel@Module+@Providesper classi di terze parti e interfacce@Singletonper condividere una sola istanza nell'intera app
Prossimo argomento: notifiche push con Firebase Cloud Messaging.
Domande Frequenti
La lezione «Dependency Injection con Hilt» è gratuita?
Sì — il testo completo di «Dependency Injection con Hilt» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Android Academy, passa a CoddyKit PRO. Il corso Android Academy include 6 lezioni in totale.
Cosa imparerò in «Dependency Injection con Hilt»?
Semplifichi la gestione delle dipendenze con Hilt. Usi @HiltAndroidApp, @AndroidEntryPoint, @HiltViewModel, @Module, @Provides e gli scope @Singleton. Eserciti Android Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Android Academy?
Non è richiesta alcuna esperienza precedente. Android Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 6 di 6.
Quanto tempo richiede la lezione «Dependency Injection con Hilt»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Android Academy?
Sì. Ogni lezione Android Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- ViewModel e LiveData
- Database Room
- Coroutines e funzioni suspend
- Pattern Repository
- Navigation Component
- Dependency Injection con Hilt