שימוש ב-Hilt עם ספריות אחרות של Jetpack

‫Hilt כולל תוספים לאספקת מחלקות מספריית Jetpack אחרות. נכון לעכשיו, Hilt תומך ברכיבי Jetpack הבאים:

  • אימייל חדש
  • ViewModel
  • ניווט
  • WorkManager

כדי להשתמש בשילובים האלה, צריך להוסיף את יחסי התלות של Hilt. מידע נוסף על הוספת יחסי תלות זמין במאמר הזרקת תלות באמצעות Hilt.

שילוב עם Jetpack פיתוח נייטיב

כדי לראות איך Hilt משתלב עם Jetpack פיתוח נייטיב, אפשר לעיין בקטע Hilt במאמר בנושא פיתוח נייטיב וספריות אחרות.

הזרקת אובייקטים של ViewModel באמצעות Hilt

מציינים ViewModel באמצעות הערה עם @HiltViewModel ושימוש בהערה @Inject בבונה של אובייקט ViewModel.

@HiltViewModel
class ExampleViewModel @Inject constructor(
  private val savedStateHandle: SavedStateHandle,
  private val repository: ExampleRepository
) : ViewModel() {
  ...
}

לאחר מכן, פעילות שמסומנת ב-@AndroidEntryPoint יכולה לקבל את מופע ViewModel כרגיל באמצעות ViewModelProvider או by viewModels() KTX extensions:

@AndroidEntryPoint
class ExampleActivity : AppCompatActivity() {
  private val exampleViewModel: ExampleViewModel by viewModels()
  ...
}

שימוש בהזרקה בעזרת ViewModels

‫Hilt תומך בהזרקה מסוג assisted ל-ViewModels. החדרת תלות בעזרת Hilt מאפשרת להחדיר ארגומנטים דינמיים של זמן ריצה לצד יחסי תלות שמנוהלים על ידי Hilt. כדי להשתמש בהוספה בעזרת תיוג, מוסיפים את התיוג @AssistedInject לבנאי של ViewModel, ומסמנים פרמטרים דינמיים באמצעות @Assisted. צריך גם להגדיר ממשק @AssistedFactory, שמשמש כגשר ל-Hilt כדי ליצור באופן אוטומטי את @ViewModelProvider.Factory הנדרש.

@HiltViewModel(assistedFactory = MyViewModel.Factory::class)
class MyViewModel @AssistedInject constructor(
    @Assisted val userId: String,
    private val repository: MyRepository
) : ViewModel() {
    @AssistedFactory interface Factory {
        fun create(userId: String): MyViewModel
    }
}

ב-Compose, אפשר להשתמש ב-assisted factory על ידי העברה שלו לפונקציה hiltViewModel במהלך הניווט או אתחול המסך. הגישה הזו מייתרת את הצורך ב-boilerplate ידני של פקטורי (factory), תוך שמירה על היקף ViewModel שמוגדר בצורה נכונה למקבץ פעילויות קודמות (back stack) של הניווט. מידע נוסף זמין במאמר בנושא הזרקה בעזרת Hilt.

@ViewModelScoped

כל ה-ViewModels של Hilt מסופקים על ידי ViewModelComponent, שפועל לפי אותו מחזור חיים כמו ViewModel, ולכן יכול לשרוד שינויים בהגדרות. כדי להגדיר את ההיקף של תלות ב-ViewModel, משתמשים בהערה @ViewModelScoped.

סוג @ViewModelScoped יגרום לכך שמופע יחיד של הסוג המוגבל יסופק בכל התלויות שמוזרקות ל-ViewModel. מופעים אחרים של ViewModel שמבקשים את המופע בהיקף יקבלו מופע אחר.

אם צריך לשתף מופע יחיד בין כמה ViewModels, צריך להגדיר לו היקף באמצעות @ActivityRetainedScoped או @Singleton.

שילוב עם ספריות הניווט של Jetpack

מוסיפים את יחסי התלות הנוספים הבאים לקובץ Gradle:

app/build.gradle

Kotlin

dependencies {
    ...
    implementation("androidx.hilt:hilt-lifecycle-viewmodel-compose:1.3.0")
}

מגניב

dependencies {
    ...
    implementation 'androidx.hilt:hilt-lifecycle-viewmodel-compose:1.3.0'
}

ב-Jetpack פיתוח נייטיב, הספריות Navigation Compose ו-Navigation 3 משתמשות בפונקציה hiltViewModel כדי לאחזר באופן אוטומטי ViewModel בהיקף של יעד הניווט הנוכחי.

בניווט 3, יעדי הניווט מיוצגים על ידי NavEntry. הגדרת היקף של ViewModels ל-NavEntrys באמצעות rememberViewModelStoreNavEntryDecorator. משתמשים ב-hiltViewModel בתוך פלאגין שמתממשק עם שירותים חיצוניים NavEntry כדי לאחזר את ViewModel המשויך.

NavDisplay(...,
  entryDecorators = listOf(..., rememberViewModelStoreNavEntryDecorator()),
  entryProvider = entryProvider {
    entry { key ->
      val viewModel = hiltViewModel()
      MyScreen(viewModel = viewModel)
    }
  }
)

ב-Navigation Compose, היקף ה-ViewModels מוגדר אוטומטית ליעדי הניווט. מידע נוסף זמין במאמר בנושא Hilt and Navigation (Hilt וניווט).

val viewModel = hiltViewModel()

החדרת WorkManager באמצעות Hilt

מוסיפים את יחסי התלות הנוספים הבאים לקובץ Gradle. שימו לב: בנוסף לספרייה, צריך לכלול מעבד אנוטציות נוסף שפועל על גבי מעבד האנוטציות של Hilt:

app/build.gradle

Kotlin

dependencies {
    implementation("androidx.hilt:hilt-work:1.0.0")
    // When using Kotlin.
    ksp("androidx.hilt:hilt-compiler:1.3.0")
}

מגניב

dependencies {
  ...
  implementation 'androidx.hilt:hilt-work:1.0.0'
  // When using Kotlin.
  ksp 'androidx.hilt:hilt-compiler:1.3.0'
}

מזריקים Worker באמצעות האנוטציה @HiltWorker במחלקה ו-@AssistedInject ב-constructor של האובייקט Worker. באובייקטים מסוג Worker אפשר להשתמש רק בקישורי @Singleton או בקישורים ללא היקף. צריך גם להוסיף הערות לתלות Context ו-WorkerParameters באמצעות @Assisted:

@HiltWorker
class ExampleWorker @AssistedInject constructor(
  @Assisted appContext: Context,
  @Assisted workerParams: WorkerParameters,
  workerDependency: WorkerDependency
) : Worker(appContext, workerParams) { ... }

לאחר מכן, מחלקה Application צריכה להטמיע את הממשק Configuration.Provider, להוסיף מופע של HiltWorkFactory ולהעביר אותו להגדרת WorkManager באופן הבא:

@HiltAndroidApp
class ExampleApplication : Application(), Configuration.Provider {

  @Inject lateinit var workerFactory: HiltWorkerFactory

  override fun getWorkManagerConfiguration() =
      Configuration.Builder()
            .setWorkerFactory(workerFactory)
            .build()
}