0Pricing
Android Academy · Lezione

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:

  • @HiltAndroidApp sulla classe Application
  • @AndroidEntryPoint su Activity e Fragment
  • @Inject constructor per le classi iniettabili
  • @HiltViewModel + @Inject constructor per i ViewModel
  • @Module + @Provides per classi di terze parti e interfacce
  • @Singleton per 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

  1. ViewModel e LiveData
  2. Database Room
  3. Coroutines e funzioni suspend
  4. Pattern Repository
  5. Navigation Component
  6. Dependency Injection con Hilt
← Torna a Android Academy