Chèn phần phụ thuộc bằng Hilt

Hilt là một thư viện chèn phần phụ thuộc cho Android, giúp giảm bớt mã nguyên mẫu trong quá trình thực hiện thao tác chèn phần phụ thuộc thủ công vào dự án của bạn. Để chèn phần phụ thuộc theo cách thủ công, bạn cần tự tay tạo từng lớp và các phần phụ thuộc tương ứng, đồng thời dùng vùng chứa để sử dụng lại cũng như quản lý các phần phụ thuộc.

Hilt cung cấp cách thức tiêu chuẩn để sử dụng DI trong ứng dụng của bạn bằng cách cung cấp các vùng chứa cho mọi lớp Android trong dự án, đồng thời tự động quản lý vòng đời của các vùng chứa đó. Hilt được xây dựng dựa trên thư viện DI phổ biến Dagger để hưởng lợi từ độ chính xác của thời gian biên dịch, hiệu suất trong thời gian chạy, khả năng có thể mở rộng và Hỗ trợ Android Studio mà Dagger cung cấp. Để biết thêm thông tin chi tiết, vui lòng xem nội dung Hilt và Dagger.

Hướng dẫn này giải thích các khái niệm cơ bản về Hilt và các vùng chứa đã tạo. Nội dung này cũng bao gồm một hướng dẫn cách khởi động một ứng dụng hiện có để sử dụng Hilt.

Thêm phần phụ thuộc

Trước tiên, hãy thêm trình bổ trợ hilt-android-gradle-plugin vào tệp build.gradle gốc trong dự án của bạn:

Kotlin

plugins {
  ...
  id("com.google.dagger.hilt.android") version "2.57.1" apply false
}

Groovy

plugins {
  ...
  id 'com.google.dagger.hilt.android' version '2.57.1' apply false
}

Sau đó, áp dụng trình bổ trợ Gradle và thêm các phần phụ thuộc này vào tệp app/build.gradle của bạn:

Kotlin

plugins {
  id("com.google.devtools.ksp")
  id("com.google.dagger.hilt.android")
}

android {
  ...
}

dependencies {
  implementation("com.google.dagger:hilt-android:2.57.1")
  ksp("com.google.dagger:hilt-android-compiler:2.57.1")
}

Groovy

...
plugins {
  id 'com.google.devtools.ksp'
  id 'com.google.dagger.hilt.android'
}

android {
  ...
}

dependencies {
  implementation "com.google.dagger:hilt-android:2.57.1"
  ksp "com.google.dagger:hilt-compiler:2.57.1"
}

Để đảm bảo dự án của bạn được định cấu hình cho Java 17 (phiên bản bắt buộc của Jetpack Compose và Hilt), hãy thêm đoạn mã sau vào tệp app/build.gradle:

Kotlin

android {
  ...
  compileOptions {
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
  }
}

Groovy

android {
  ...
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_17
    targetCompatibility JavaVersion.VERSION_17
  }
}

Lớp ứng dụng Hilt

Tất cả ứng dụng sử dụng Hilt phải chứa một lớp Application được chú thích bằng @HiltAndroidApp.

@HiltAndroidApp kích hoạt việc tạo mã của Hilt, bao gồm một lớp cơ sở cho ứng dụng của bạn, đóng vai trò là vùng chứa phần phụ thuộc cấp ứng dụng.

@HiltAndroidApp
class ExampleApplication : Application() { ... }

Thành phần Hilt đã tạo này được gắn vào vòng đời của đối tượng Application và cung cấp các phần phụ thuộc tương ứng. Ngoài ra, đây là thành phần mẹ của ứng dụng, nghĩa là các thành phần khác có thể truy cập vào các phần phụ thuộc mà thành phần Hilt cung cấp.

Chèn phần phụ thuộc vào các lớp Android

Sau khi được thiết lập trong lớp Application và có sẵn một thành phần cấp ứng dụng, Hilt có thể cung cấp phần phụ thuộc cho các lớp Android khác với chú thích @AndroidEntryPoint:

@AndroidEntryPoint
class ExampleActivity : ComponentActivity() { ... }

Hilt hiện hỗ trợ các lớp Android sau:

  • Application (bằng cách sử dụng @HiltAndroidApp)
  • ViewModel (bằng cách sử dụng @HiltViewModel)
  • Activity
  • Service
  • BroadcastReceiver

Trong Compose, bạn không cần chú thích các thành phần kết hợp riêng lẻ. Thay vào đó, hãy chú giải ComponentActivity gốc bằng @AndroidEntryPoint. Đây là điểm truy cập DI duy nhất cho toàn bộ hệ phân cấp giao diện người dùng, vì vậy, bạn có thể truy cập trực tiếp vào các ViewModel được Hilt chèn trong các hàm kết hợp.

@AndroidEntryPoint tạo một thành phần Hilt riêng lẻ cho từng lớp Android trong dự án. Các thành phần này có thể nhận được phần phụ thuộc từ các lớp cha tương ứng như mô tả trong Hệ phân cấp thành phần.

Để lấy các phần phụ thuộc từ một thành phần, hãy sử dụng chú thích @Inject để thực hiện thao tác chèn trường:

@AndroidEntryPoint
class ExampleActivity : ComponentActivity() {

  @Inject lateinit var analytics: AnalyticsAdapter
  ...
}

Các lớp do Hilt chèn vào có thể có các lớp cơ sở khác cũng sử dụng tính năng chèn. Các lớp đó không cần chú thích @AndroidEntryPoint nếu chúng mang tính trừu tượng.

Để tìm hiểu thêm về phương thức gọi lại trong vòng đời mà một lớp Android được chèn vào, vui lòng xem phần Vòng đời của thành phần.

Xác định các liên kết Hilt

Để thực hiện thao tác chèn trường, Hilt cần biết cách cung cấp thực thể của các phần phụ thuộc cần thiết từ thành phần tương ứng. Liên kết chứa thông tin cần thiết để cung cấp các phiên bản của một loại dưới dạng phần phụ thuộc.

Một cách để cung cấp thông tin liên kết cho Hilt là sử dụng tính năng chèn hàm khởi tạo. Hãy sử dụng chú thích @Inject trên hàm khởi tạo của một lớp để cho Hilt biết cách cung cấp các bản sao của lớp đó:

class AnalyticsAdapter @Inject constructor(
  private val service: AnalyticsService
) { ... }

Các tham số của một hàm khởi tạo có chú thích của một lớp là các phần phụ thuộc của lớp đó. Trong ví dụ, AnalyticsAdapterAnalyticsService là phần phụ thuộc. Do đó, Hilt cũng phải biết cách cung cấp các bản sao của AnalyticsService.

Mô-đun Hilt

Đôi khi không thể chèn một loại vào hàm khởi tạo. Điều này có thể xảy ra vì nhiều lý do. Ví dụ như bạn không thể chèn một giao diện vào hàm khởi tạo. Bạn cũng không thể chèn một loại mà bạn không sở hữu vào hàm khởi tạo, chẳng hạn như một lớp từ thư viện bên ngoài. Trong những trường hợp này, bạn có thể cung cấp cho Hilt thông tin liên kết bằng cách dùng mô-đun Hilt.

Mô-đun Hilt là một lớp được chú thích bằng @Module. Nó cung cấp cho Hilt hướng dẫn về cách tạo các thực thể của những loại không thể cung cấp thông qua phương thức chèn hàm khởi tạo, chẳng hạn như giao diện hoặc các lớp bên thứ ba. Bạn cũng phải chú thích mọi mô-đun bằng @InstallIn để cho Hilt biết mỗi mô-đun sẽ được sử dụng hoặc cài đặt trong lớp Android nào.

Các phần phụ thuộc mà bạn cung cấp trong mô-đun Hilt có sẵn trong tất cả các thành phần được tạo liên kết với lớp Android nơi bạn cài đặt mô-đun Hilt.

Chèn thực thể giao diện bằng @Binds

Hãy xem xét ví dụ về AnalyticsService. Nếu AnalyticsService là một giao diện, thì bạn không thể dùng nó để chèn hàm khởi tạo. Thay vào đó, hãy cung cấp thông tin liên kết cho Hilt bằng cách tạo một hàm trừu tượng có chú thích bằng @Binds bên trong mô-đun Hilt.

Chú thích @Binds sẽ cho Hilt biết phương thức triển khai nào được sử dụng khi cần cung cấp một bản sao của giao diện.

Hàm được chú thích sẽ cung cấp các thông tin sau cho Hilt:

  • Loại dữ liệu trả về của hàm cho Hilt biết bản sao của giao diện mà hàm cung cấp.
  • Tham số hàm cho Hilt biết phương thức triển khai nào cần cung cấp.
interface AnalyticsService {
  fun analyticsMethods()
}

// Constructor-injected, because Hilt needs to know how to
// provide instances of AnalyticsServiceImpl, too.
class AnalyticsServiceImpl @Inject constructor(
  ...
) : AnalyticsService { ... }

@Module
@InstallIn(ActivityComponent::class)
abstract class AnalyticsModule {

  @Binds
  abstract fun bindAnalyticsService(
    analyticsServiceImpl: AnalyticsServiceImpl
  ): AnalyticsService
}

Mô-đun Hilt AnalyticsModule được chú thích bằng @InstallIn(ActivityComponent.class) vì bạn muốn Hilt chèn phần phụ thuộc đó vào ExampleActivity. Chú thích này có nghĩa là tất cả phần phụ thuộc trong AnalyticsModule đều có trong mọi hoạt động của ứng dụng.

Chèn thực thể bằng @Provides

Giao diện không phải là trường hợp duy nhất nơi bạn không thể chèn hàm khởi tạo. Bạn cũng không thể chèn hàm khởi tạo nếu bạn không sở hữu lớp đó vì nó đến từ thư viện bên ngoài (chẳng hạn như các lớp Retrofit, OkHttpClient hoặc Cơ sở dữ liệu phòng), hoặc nếu bản sao phải được tạo bằngmẫu trình tạo .

Hãy xem xét ví dụ trước. Nếu không trực tiếp sở hữu lớp AnalyticsService, thì bạn có thể cho Hilt biết cách cung cấp các bản sao của loại này bằng cách tạo một hàm bên trong mô-đun Hilt và chú thích hàm đó bằng @Provides.

Hàm được chú thích cung cấp các thông tin sau cho Hilt:

  • Loại dữ liệu trả về của hàm cho Hilt biết loại mà hàm cung cấp các bản sao.
  • Các tham số hàm cho Hilt biết các phần phụ thuộc của loại tương ứng.
  • Phần nội dung hàm cho Hilt biết cách cung cấp một bản sao của loại tương ứng. Hilt thực thi phần nội dung hàm mỗi khi cần cung cấp một phiên bản của loại đó.
@Module
@InstallIn(ActivityComponent::class)
object AnalyticsModule {

  @Provides
  fun provideAnalyticsService(
    // Potential dependencies of this type
  ): AnalyticsService {
      return Retrofit.Builder()
               .baseUrl("https://example.com")
               .build()
               .create(AnalyticsService::class.java)
  }
}

Cung cấp nhiều liên kết cho cùng một loại

Trong trường hợp bạn cần Hilt cung cấp các cách triển khai khác nhau của cùng một loại làm phần phụ thuộc, bạn phải cung cấp cho Hilt nhiều đường liên kết. Bạn có thể xác định nhiều liên kết cho cùng một loại bằng bộ hạn định.

Bộ hạn định là chú thích mà bạn dùng để xác định một mối liên kết cụ thể cho một loại khi loại đó có nhiều liên kết được xác định.

Hãy xem xét ví dụ. Nếu cần chặn các lệnh gọi đến AnalyticsService, bạn có thể sử dụng đối tượng OkHttpClient bằng một trình chặn. Đối với các dịch vụ khác, bạn có thể cần chặn lệnh gọi theo một cách khác. Trong trường hợp đó, bạn cần cho Hilt biết cách cung cấp hai cách triển khai OkHttpClient khác nhau.

Trước tiên, hãy xác định những bộ hạn định bạn sẽ sử dụng để chú thích các phương thức @Binds hoặc @Provides:

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class AuthInterceptorOkHttpClient

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class OtherInterceptorOkHttpClient

Sau đó, Hilt cần biết cách cung cấp một bản sao của loại tương ứng với từng bộ hạn định. Trong trường hợp này, bạn có thể sử dụng mô-đun Hilt với @Provides. Cả hai phương thức đều có cùng một loại dữ liệu trả về, nhưng những bộ hạn định này gắn nhãn chúng dưới dạng hai liên kết khác nhau:

@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {

  @AuthInterceptorOkHttpClient
  @Provides
  fun provideAuthInterceptorOkHttpClient(
    authInterceptor: AuthInterceptor
  ): OkHttpClient {
      return OkHttpClient.Builder()
               .addInterceptor(authInterceptor)
               .build()
  }

  @OtherInterceptorOkHttpClient
  @Provides
  fun provideOtherInterceptorOkHttpClient(
    otherInterceptor: OtherInterceptor
  ): OkHttpClient {
      return OkHttpClient.Builder()
               .addInterceptor(otherInterceptor)
               .build()
  }
}

Bạn có thể chèn loại cụ thể mà bạn cần bằng cách chú thích trường hoặc tham số bằng bộ hạn định tương ứng:

// As a dependency of another class.
@Module
@InstallIn(ActivityComponent::class)
object AnalyticsModule {

  @Provides
  fun provideAnalyticsService(
    @AuthInterceptorOkHttpClient okHttpClient: OkHttpClient
  ): AnalyticsService {
      return Retrofit.Builder()
               .baseUrl("https://example.com")
               .client(okHttpClient)
               .build()
               .create(AnalyticsService::class.java)
  }
}

// As a dependency of a constructor-injected class.
class ExampleServiceImpl @Inject constructor(
  @AuthInterceptorOkHttpClient private val okHttpClient: OkHttpClient
) : ...

// At field injection.
@AndroidEntryPoint
class ExampleActivity: ComponentActivity() {

  @AuthInterceptorOkHttpClient
  @Inject lateinit var okHttpClient: OkHttpClient
}

Phương pháp hay nhất là nếu bạn thêm bộ hạn định vào một loại, hãy thêm bộ hạn định vào bằng mọi cách có thể để cung cấp phần phụ thuộc đó. Nếu bạn rời khỏi việc triển khai cơ sở hoặc triển khai chung mà không có bộ hạn định thì rất dễ xảy ra lỗi, ngoài ra còn có thể dẫn đến tình trạng chèn sai phần phụ thuộc.

Bộ hạn định được xác định trước trong Hilt

Hilt cung cấp một số bộ hạn định được xác định trước. Chẳng hạn như vì bạn có thể cần lớp Context từ ứng dụng hoặc hoạt động, nên Hilt sẽ cung cấp bộ hạn định @ApplicationContext@ActivityContext.

Giả sử lớp AnalyticsAdapter từ ví dụ cần ngữ cảnh của hoạt động. Đoạn mã sau đây minh hoạ cách cung cấp ngữ cảnh hoạt động cho AnalyticsAdapter:

class AnalyticsAdapter @Inject constructor(
    @ActivityContext private val context: Context,
    private val service: AnalyticsService
) { ... }

Để biết các liên kết được xác định trước khác có sẵn trong Hilt, vui lòng xem nội dung phần Liên kết mặc định của thành phần.

Các thành phần đã tạo cho lớp Android

Đối với mỗi lớp Android mà bạn có thể thực hiện thao tác chèn trường, có một thành phần Hilt đi kèm mà bạn có thể tham khảo trong chú thích @InstallIn. Mỗi thành phần Hilt chịu trách nhiệm chèn các liên kết vào lớp Android tương ứng.

Các ví dụ trước cho thấy cách sử dụng ActivityComponent trong các mô-đun Hilt.

Hilt cung cấp các thành phần sau:

Thành phần Hilt Trình chèn cho
SingletonComponent Application
ActivityRetainedComponent Không áp dụng
ViewModelComponent ViewModel
ActivityComponent Activity
ServiceComponent Service

Vòng đời của thành phần

Hilt tự động tạo và huỷ các phiên bản của lớp thành phần được tạo theo vòng đời của các lớp Android tương ứng.

Thành phần đã tạo Được tạo ở Bị hủy ở
SingletonComponent Application#onCreate() Application đã huỷ bỏ
ActivityRetainedComponent Activity#onCreate() Activity#onDestroy()
ViewModelComponent Đã tạo ViewModel Đã huỷ bỏ ViewModel
ActivityComponent Activity#onCreate() Activity#onDestroy()
ServiceComponent Service#onCreate() Service#onDestroy()

Các phạm vi thành phần

Theo mặc định, tất cả các đường liên kết trong Hilt đều không có phạm vi. Tức là mỗi khi ứng dụng yêu cầu liên kết, Hilt sẽ tạo một bản sao mới của loại cần thiết.

Ở ví dụ này, mỗi khi Hilt cung cấp AnalyticsAdapter dưới dạng một phần phụ thuộc vào một loại khác hoặc thông qua tính năng chèn trường (như trong ExampleActivity), Hilt sẽ cung cấp một thực thể mới của AnalyticsAdapter.

Tuy nhiên, Hilt cũng cho phép đưa liên kết vào một thành phần cụ thể. Hilt chỉ tạo liên kết theo phạm vi một lần cho mỗi thực thể của thành phần mà liên kết đó được xác định phạm vi và mọi yêu cầu cho liên kết đó đều chia sẻ cùng một thực thể.

Bảng dưới đây liệt kê các chú thích phạm vi cho từng thành phần được tạo:

Lớp Android Thành phần đã tạo Phạm vi
Application SingletonComponent @Singleton
Activity ActivityRetainedComponent @ActivityRetainedScoped
ViewModel ViewModelComponent @ViewModelScoped
Activity ActivityComponent @ActivityScoped
Service ServiceComponent @ServiceScoped

Trong ví dụ, nếu bạn đặt phạm vi của AnalyticsAdapter thành ActivityComponent bằng @ActivityScoped, thì Hilt sẽ cung cấp cùng một phiên bản của AnalyticsAdapter trong suốt thời gian của hoạt động tương ứng:

@ActivityScoped
class AnalyticsAdapter @Inject constructor(
  private val service: AnalyticsService
) { ... }

Giả sử AnalyticsService có trạng thái nội bộ yêu cầu sử dụng cùng một phiên bản mọi lúc — không chỉ trong ExampleActivity mà còn ở mọi nơi trong ứng dụng. Trong trường hợp này, bạn nên đặt phạm vi của AnalyticsService thành SingletonComponent. Theo đó, bất cứ khi nào thành phần cần cung cấp một phiên bản của AnalyticsService, thành phần đó sẽ cung cấp cùng một phiên bản mọi lúc.

Ví dụ sau minh họa cách xác định phạm vi liên kết với một thành phần trong mô-đun Hilt. Phạm vi của liên kết phải khớp với phạm vi của thành phần nơi nó được cài đặt, vì vậy trong ví dụ này, bạn phải cài đặt AnalyticsService trong SingletonComponent thay vì ActivityComponent:

// If AnalyticsService is an interface.
@Module
@InstallIn(SingletonComponent::class)
abstract class AnalyticsModule {

  @Singleton
  @Binds
  abstract fun bindAnalyticsService(
    analyticsServiceImpl: AnalyticsServiceImpl
  ): AnalyticsService
}

// If you don't own AnalyticsService.
@Module
@InstallIn(SingletonComponent::class)
object AnalyticsModule {

  @Singleton
  @Provides
  fun provideAnalyticsService(): AnalyticsService {
      return Retrofit.Builder()
               .baseUrl("https://example.com")
               .build()
               .create(AnalyticsService::class.java)
  }
}

Để tìm hiểu thêm về phạm vi thành phần trong Hilt, vui lòng xem nội dung phần Xác định phạm vi trong Android và Hilt.

Hệ phân cấp thành phần

Việc cài đặt một mô-đun vào một thành phần cho phép các liên kết của mô-đun đó được truy cập dưới dạng phần phụ thuộc của các liên kết khác trong thành phần đó hoặc trong bất kỳ thành phần con nào bên dưới nó trong hệ thống phân cấp thành phần.

ActivityComponent nằm trong ActivityRetainedComponent. ViewModelComponent nằm trong ActivityRetainedComponent. ActivityRetainedComponent và ServiceComponent nằm trong SingletonComponent.
Hình 1. Hệ phân cấp các thành phần mà Hilt tạo ra.

Liên kết mặc định của thành phần

Mỗi thành phần Hilt đi kèm với một tập hợp các liên kết mặc định mà Hilt có thể chèn dưới dạng phần phụ thuộc vào các liên kết tuỳ chỉnh của riêng bạn. Lưu ý rằng các liên kết này tương ứng với loại hoạt động chung chứ không phải bất kỳ lớp con cụ thể nào. Điều này là do Hilt sử dụng một định nghĩa thành phần hoạt động duy nhất để chèn tất cả các hoạt động. Mỗi hoạt động có một bản sao khác của thành phần này.

Thành phần Android Các liên kết mặc định
SingletonComponent Application
ActivityRetainedComponent Application
ViewModelComponent SavedStateHandle
ActivityComponent Application, Activity
ServiceComponent Application, Service

Liên kết ngữ cảnh ứng dụng cũng có sẵn bằng cách sử dụng @ApplicationContext. Ví dụ:

class AnalyticsServiceImpl @Inject constructor(
  @ApplicationContext context: Context
) : AnalyticsService { ... }

// The Application binding is available without qualifiers.
class AnalyticsServiceImpl @Inject constructor(
  application: Application
) : AnalyticsService { ... }

Bạn cũng có thể liên kết ngữ cảnh hoạt động bằng cách sử dụng @ActivityContext. Ví dụ:

class AnalyticsAdapter @Inject constructor(
  @ActivityContext context: Context
) { ... }

// The Activity binding is available without qualifiers.
class AnalyticsAdapter @Inject constructor(
  activity: ComponentActivity
) { ... }

Chèn các phần phụ thuộc vào các lớp không được Hilt hỗ trợ

Trong Compose, mẫu tiêu chuẩn là chèn các phần phụ thuộc vào @HiltViewModel bằng cách sử dụng phương thức chèn hàm khởi tạo, sau đó sử dụng hiltViewModel() bên trong thành phần kết hợp để truy cập vào ViewModel. Mặc dù Hilt hỗ trợ các lớp Android phổ biến nhất, nhưng bạn vẫn có thể gặp phải các lớp không được hỗ trợ mà bạn cần thực hiện thao tác chèn trường.

Trong những trường hợp đó, bạn có thể tạo một điểm truy cập bằng cách sử dụng chú thích @EntryPoint. Điểm truy cập là ranh giới giữa mã do Hilt quản lý và mã không phải do Hilt quản lý. Đây là điểm đầu tiên mã nhập vào biểu đồ của các đối tượng mà Hilt quản lý. Điểm truy cập cho phép Hilt sử dụng mã mà Hilt không quản lý để cung cấp các phần phụ thuộc trong biểu đồ phần phụ thuộc.

Chẳng hạn như Hilt không trực tiếp hỗ trợ các nhà cung cấp nội dung. Nếu muốn nhà cung cấp nội dung sử dụng Hilt để lấy một số phần phụ thuộc, thì bạn cần xác định giao diện được chú thích bằng @EntryPoint cho từng loại liên kết mà bạn muốn và đưa bộ hạn định vào. Sau đó, hãy thêm @InstallIn để chỉ định thành phần cần cài đặt điểm truy cập như sau:

class ExampleContentProvider : ContentProvider() {

  @EntryPoint
  @InstallIn(SingletonComponent::class)
  interface ExampleContentProviderEntryPoint {
    fun analyticsService(): AnalyticsService
  }

  ...
}

Để truy cập vào một điểm truy cập, hãy sử dụng phương thức tĩnh thích hợp từ EntryPointAccessors. Tham số này phải là bản sao của thành phần hoặc đối tượng @AndroidEntryPoint, đóng vai trò là chủ thể thành phần. Hãy đảm bảo là thành phần bạn truyền dưới dạng tham số và phương thức tĩnh EntryPointAccessors đều khớp với lớp Android trong chú thích @InstallIn trên giao diện @EntryPoint:

class ExampleContentProvider: ContentProvider() {
    ...

  override fun query(...): Cursor {
    val appContext = context?.applicationContext ?: throw IllegalStateException()
    val hiltEntryPoint =
      EntryPointAccessors.fromApplication(appContext, ExampleContentProviderEntryPoint::class.java)

    val analyticsService = hiltEntryPoint.analyticsService()
    ...
  }
}

Trong ví dụ này, bạn phải sử dụng ApplicationContext để truy xuất điểm truy cập vì điểm truy cập đó được cài đặt trong SingletonComponent. Nếu liên kết mà bạn muốn truy xuất nằm trong ActivityComponent, bạn nên dùng ActivityContext.

Hilt và Dagger

Hilt là thư viện được đề xuất chính thức để chèn phần phụ thuộc trong Android. Hilt cung cấp một cách tiêu chuẩn hoá, có ý kiến và hiệu quả để triển khai tính năng chèn phần phụ thuộc trong ứng dụng của bạn, đặc biệt được tối ưu hoá cho Jetpack Compose và cấu trúc một hoạt động.

Sau đây là các mục tiêu của Hilt:

  • Tạo một nhóm thành phần và phạm vi tiêu chuẩn để dễ dàng thiết lập, dễ đọc và chia sẻ mã giữa các ứng dụng.
  • Mang đến phương thức dễ dàng để cung cấp nhiều mối liên kết cho nhiều loại bản dựng, chẳng hạn như kiểm thử, gỡ lỗi hoặc phát hành.

Vì hệ điều hành Android tạo bản sao của nhiều lớp khung cho riêng nó, nên việc sử dụng Dagger trong ứng dụng Android sẽ yêu cầu bạn viết một lượng lớn các mã nguyên mẫu. Hilt sẽ giúp giảm mã nguyên mẫu có liên quan đến việc sử dụng Dagger trong ứng dụng Android. Hilt tự động tạo và cung cấp các mục sau:

  • Các thành phần để tích hợp lớp khung Android với Dagger mà bạn cần phải tạo theo cách thủ công nếu không có các thành phần này.
  • Chú thích phạm vi để sử dụng với các thành phần mà Hilt tạo tự động.
  • Các đường liên kết được xác định trước để đại diện cho các lớp Android, chẳng hạn như Application hoặc Activity.
  • Bộ hạn định xác định trước đại diện cho @ApplicationContext@ActivityContext.

Mã Dagger và Hilt có thể cùng tồn tại trong cùng một cơ sở mã. Tuy nhiên, trong hầu hết các trường hợp, bạn nên sử dụng Hilt để quản lý toàn bộ việc sử dụng Dagger trên Android. Để di chuyển một dự án sử dụng Dagger sang Hilt, hãy xem hướng dẫn di chuyển.

Tài nguyên khác

Để tìm hiểu thêm về Hilt, vui lòng xem các tài nguyên bổ sung sau đây:

Mẫu

Blog

Xem nội dung