Android Academy · Oppitunti

Riippuvuuksien injektointi Hiltillä

Yksinkertaistakaa riippuvuuksien hallintaa Hiltillä. Käyttäkää @HiltAndroidApp-, @AndroidEntryPoint-, @HiltViewModel- ja @Module-annotaatioita sekä @Provides- ja @Singleton-määreitä.

Oppitunti 6/613 vaihetta

Riippuvuuksien injektointi Hiltillä on ilmainen Android Academy-oppitunti CoddyKitissä. Tämä on oppitunti 6/6. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu Android Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Android Academy-kurssilla on yhteensä 6 oppituntia.

Mitä on riippuvuuksien injektointi?

Riippuvuuksien injektointi (Dependency Injection, DI) tarkoittaa, että oliolle tarjotaan sen tarvitsemat riippuvuudet sen sijaan, että se loisi ne itse.

Ilman DI:tä luokka luo omat riippuvuutensa — riippuvuudet ovat tiukasti sidottuja ja testaaminen on vaikeaa. DI:n kanssa riippuvuudet injektoidaan ulkopuolelta — kytkös on löyhä, ja testaaminen sekä toteutusten vaihtaminen on helppoa.

Manuaalinen DI ja Hilt

Manuaalinen DI toimii, mutta sen käyttö muuttuu työlääksi sovelluksen kasvaessa:

// 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()

Hiltin lisääminen

Lisää Hilt projektiisi:

// 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

Merkitse Application-luokkasi annotaatiolla @HiltAndroidApp. Se on Hilt-komponenttihierarkian lähtöpiste:

@HiltAndroidApp
class MyApp : Application()

// Also register in AndroidManifest.xml:
// <application android:name=".MyApp" ...>

@AndroidEntryPoint

Lisää @AndroidEntryPoint Activityihin, fragmentteihin ja palveluihin, jotka tarvitsevat injektoituja riippuvuuksia:

@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 — konstruktorin injektointi

Merkitse konstruktori annotaatiolla @Inject ilmoittaaksesi Hiltille, miten luokka luodaan. Hilt ratkaisee kaikki parametrit automaattisesti:

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

Merkitse ViewModel annotaatiolla @HiltViewModel ja käytä @Inject constructor -konstruktoria. Hae ViewModel fragmentissa komennolla 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 ja @Provides

Kun Hilt ei voi käyttää konstruktorin injektointia (esimerkiksi rajapintojen tai kolmannen osapuolen luokkien kanssa), tarjoa oliot @Module-moduulin kautta:

@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 — rajapinnan sidonta

Käytä @Binds-annotaatiota ilmoittaaksesi Hiltille, mitä toteutusta rajapinnalle käytetään:

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
}

Hiltin scopet

Scopet määrittävät, kuinka kauan injektoitu olio säilyy:

  • @Singleton — yksi olio sovelluksen koko elinkaaren ajan (ApplicationComponent)
  • @ActivityRetainedScoped — säilyy kokoonpanomuutosten yli
  • @ActivityScoped — yksi olio Activitya kohden
  • @FragmentScoped — yksi olio fragmenttia kohden
  • @ViewModelScoped — yksi olio ViewModelia kohden

Testaaminen Hiltillä

Korvaa oikeat riippuvuudet testeissä valetoteutuksilla Hiltin testituen avulla:

@HiltAndroidTest
class UserRepositoryTest {

    @get:Rule
    val hiltRule = HiltAndroidRule(this)

    @Inject
    lateinit var repo: UserRepository

    @Before
    fun setUp() {
        hiltRule.inject()
    }

    @Test
    fun usersAreFetched() {
        assertNotNull(repo)
    }
}

Pikakertaus

Mikä annotaatio käskee Hiltiä luomaan DI-komponenttihierarkian koko sovellukselle?

Kertaus: Hiltin riippuvuuksien injektointi

Hilt tekee DI:stä lähes automaattista Androidissa:

  • @HiltAndroidApp Application-luokassa
  • @AndroidEntryPoint Activityissa ja fragmenteissa
  • @Inject constructor injektoitavissa luokissa
  • @HiltViewModel ja @Inject constructor ViewModeleissa
  • @Module ja @Provides kolmannen osapuolen luokille ja rajapinnoille
  • @Singleton yhden olion jakamiseen koko sovelluksessa

Seuraavaksi: push-ilmoitukset Firebase Cloud Messagingillä.

Aloita maksutta

Opi Kotlin tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
36
Oppitunnit
152

Usein kysytyt kysymykset

Onko oppitunti ”Riippuvuuksien injektointi Hiltillä” ilmainen?

Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Android Academy-oppimispolun 3 oppituntia, myös oppitunnin “Riippuvuuksien injektointi Hiltillä”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Android Academy-kurssilla on yhteensä 6 oppituntia.

Mitä opin oppitunnilla ”Riippuvuuksien injektointi Hiltillä”?

Yksinkertaistakaa riippuvuuksien hallintaa Hiltillä. Käyttäkää @HiltAndroidApp-, @AndroidEntryPoint-, @HiltViewModel- ja @Module-annotaatioita sekä @Provides- ja @Singleton-määreitä. Harjoittelet Android Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Android Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Android Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 6/6.

Kuinka kauan ”Riippuvuuksien injektointi Hiltillä”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Android Academy-oppitunnilla?

Kyllä. Jokainen Android Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. ViewModel ja LiveData
  2. Room-tietokanta
  3. Korutiinit ja suspend-funktiot
  4. Repository-malli
  5. Navigation Component
  6. Riippuvuuksien injektointi Hiltillä
← Takaisin: Android Academy