주의! 본 포스팅은 ChatGPT를 통해 만들었습니다
Caution! This Posting was made with ChatGPT
Using Hilt for Dependency Injection in Android
As your Android app grows in complexity, you may find yourself dealing with dependencies between classes that are hard to manage and test. One solution to this problem is to use a dependency injection (DI) framework to help manage your dependencies and make your code more modular and testable. In this blog post, we'll look at how to use Hilt, a new DI framework built on top of Dagger, to simplify dependency injection in your Android app.
What is Hilt?
Hilt is a dependency injection framework for Android that is built on top of Dagger. Dagger is a popular DI framework for Java and Android, but it can be difficult to use and set up. Hilt aims to simplify the use of Dagger by providing a set of predefined components and annotations that make it easy to use Dagger in your Android app.
Hilt is built on top of Dagger, so it benefits from all of Dagger's features, including compile-time verification of dependencies, easy testing, and more. However, Hilt provides a simpler, more streamlined API that makes it easier to get started with DI in your Android app.
Setting up Hilt
To use Hilt in your Android app, you'll need to add the following dependencies to your project:
// Hilt
implementation 'com.google.dagger:hilt-android:2.40.5'
kapt 'com.google.dagger:hilt-android-compiler:2.40.5'
These dependencies add the necessary Hilt and Dagger libraries to your project.
Next, you'll need to annotate your Application class with the @HiltAndroidApp annotation:
@HiltAndroidApp
class MyApplication : Application() {
// ...
}
This annotation tells Hilt to generate the necessary code for dependency injection in your app.
Using Hilt to Inject Dependencies
Once you've set up Hilt in your app, you can start using it to inject dependencies into your app's components. To do this, you'll need to annotate your components with the @AndroidEntryPoint annotation:
@AndroidEntryPoint
class MyActivity : AppCompatActivity() {
@Inject lateinit var myViewModel: MyViewModel
// ...
}
In this example, MyActivity is annotated with @AndroidEntryPoint, which tells Hilt to generate the necessary code to inject dependencies into the activity. The myViewModel property is annotated with @Inject, which tells Hilt to inject an instance of MyViewModel into the activity.
You can use the @Inject annotation to inject dependencies into any class that is managed by Hilt, including activities, fragments, and view models.
Injecting ViewModels with Hilt
In addition to injecting dependencies into your activities, fragments, and services, you can also use Hilt to inject ViewModels into your app.
To use Hilt to inject a ViewModel, you'll need to follow these steps:
- Add the @HiltViewModel annotation to your ViewModel class.
- Use the @Inject annotation to inject any dependencies your ViewModel needs, including the SavedStateHandle if necessary.
- Use the by viewModels() delegate to automatically create an instance of your ViewModel with any dependencies it needs.
Here's an example:
@HiltViewModel
class MyViewModel @Inject constructor(
private val myRepository: MyRepository,
@Assisted private val savedStateHandle: SavedStateHandle
) : ViewModel() {
// ...
}
In this example, we're injecting an instance of MyRepository and SavedStateHandle into our MyViewModel using the @Inject and @Assisted annotations, respectively. The SavedStateHandle class is provided by the Android framework and can be used to save and restore state information between configuration changes. By using @Assisted, we're telling Hilt that SavedStateHandle should be injected into our ViewModel's constructor, but that it should be provided by the Android framework rather than by Hilt.
To use this ViewModel in your activity or fragment, you can simply annotate your ViewModel field with the @ViewModelInject annotation and use the by viewModels() delegate to automatically create an instance of your ViewModel with any dependencies it needs, like this:
@AndroidEntryPoint
class MyActivity : AppCompatActivity() {
private val myViewModel: MyViewModel by viewModels()
// ...
}
In this example, we're using the by viewModels() delegate to create an instance of MyViewModel and pass in an instance of SavedStateHandle if necessary. The by viewModels() delegate is a shortcut provided by the Android framework that automatically creates an instance of MyViewModel using the HiltViewModelFactory and passes in any dependencies it needs, including SavedStateHandle if it is annotated with @Assisted.
By using Hilt to inject ViewModels into your app, you can simplify your ViewModel setup and reduce the amount of boilerplate code you need to write.
Creating Hilt Modules
In addition to using Hilt to inject dependencies into your app's components, you can also create your own Hilt modules to provide dependencies to your app. To create a Hilt module, you'll need to create a new Kotlin file and annotate it with the @Module annotation:
@Module
@InstallIn(ApplicationComponent::class)
class MyModule {
@Provides
fun provideMyDependency(): MyDependency {
return MyDependency()
}
}
Here, MyModule is a Dagger module that provides a dependency for MyDependency. The @InstallIn annotation tells Hilt that the module should be installed in the ApplicationComponent, which is the top-level Dagger component in your app.
The @Provides annotation is used to provide an instance of MyDependency. This tells Hilt that whenever an instance of MyDependency is requested, it should provide an instance returned by the provideMyDependency function.
Using @Binds and @Singleton Annotations
In addition to using the @Provides annotation, you can also use the @Binds annotation to provide dependencies in your Hilt modules. The @Binds annotation is more efficient than @Provides because it generates less code at compile time.
To use the @Binds annotation, you'll need to create an abstract function that returns the type of the dependency you want to provide. Here's an example:
@Module
@InstallIn(ApplicationComponent::class)
abstract class MyModule {
@Binds
abstract fun bindMyDependency(myDependencyImpl: MyDependencyImpl): MyDependency
@Singleton
@Provides
fun provideMyDependencyImpl(): MyDependencyImpl {
return MyDependencyImpl()
}
}
In this example, we're using the @Binds annotation to provide an instance of MyDependency. The bindMyDependency function takes an instance of MyDependencyImpl and returns it as a MyDependency. This tells Hilt that whenever an instance of MyDependency is requested, it should return the instance of MyDependencyImpl returned by the provideMyDependencyImpl function.
Note that we're also using the @Singleton annotation to indicate that MyDependencyImpl should be a singleton instance. This means that there will only ever be one instance of MyDependencyImpl in your app.
Creating Custom Scopes
In addition to using the predefined Dagger components and scopes provided by Hilt, you can also create your own custom scopes to manage the lifecycle of your dependencies. To create a custom scope, you'll need to create a new annotation and a new Dagger component.
Here's an example:
@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class MyCustomScope
@MyCustomScope
@Subcomponent
interface MyCustomComponent {
// ...
}
In this example, we're creating a custom scope called MyCustomScope. This scope is defined by the @Scope annotation. We're also creating a new Dagger subcomponent called MyCustomComponent. This subcomponent is annotated with @MyCustomScope, which tells Hilt that any dependencies provided by this component should be scoped to the MyCustomScope.
You can use the @MyCustomScope annotation to annotate your Hilt modules and components to indicate that they should be scoped to your custom scope.
Conclusion
In this blog post, we've looked at how to use Hilt to simplify dependency injection in your Android app. We've seen how to set up Hilt, inject dependencies into your app's components, create Hilt modules, use @Binds and @Singleton annotations, and create custom scopes.
By using Hilt, you can make your code more modular and testable, and reduce the complexity of managing dependencies in your Android app.
https://developer.android.com/training/dependency-injection/hilt-android
'Android' 카테고리의 다른 글
[개발 정보] 코틀린 코루틴 레시피(활용법) (0) | 2023.04.24 |
---|---|
[Android] Gson을 대체하는 Moshi (0) | 2023.03.10 |
[Android] ProgressBar setIndeterminateDrawable 오류 (0) | 2022.05.12 |
[Android] Dagger & Hilt ViewModelFactory (0) | 2022.04.22 |
[Android] Gson 과 android.location.Location (0) | 2022.04.15 |