what is hilt?
Hilt是基于Dagger构建而成的依赖注入框架,它提供了一种将Dagger纳入Android应用的标准方法:使用Hilt提供的规范来实现依赖注入,可以避免很多不必要的问题。
使用Hilt快速实现依赖注入
根目录 build.gradle.kts(项目根)、app/build.gradle.kts(模块)
先在根插件声明,apply false,子模块按需引入
Kotlin
plugins {
id("com.google.dagger.hilt.android") version "2.57.1" apply false
id("com.google.devtools.ksp") version "2.0.21-1.0.28" apply false
}
Kotlin
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.google.devtools.ksp")
id("com.google.dagger.hilt.android")
}
android {
namespace = "com.motionguardian.hiltdemo"
compileSdk = 36
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
implementation("com.google.dagger:hilt-android:2.57.1")
ksp("com.google.dagger:hilt-android-compiler:2.57.1")
}
Application 入口
Kotlin
package com.motionguardian.hiltdemo
import android.app.Application
import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
class MyApp : Application()
@HiltAndroidApp 标记全局根容器,KSP 编译期自动生成 Hilt_MyApp。 必须在AndroidManifest.xml 注册:
XML
<application
android:name=".MyApp"
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name">
待注入类 User
Kotlin
package com.motionguardian.hiltdemo
import javax.inject.Inject
class User @Inject constructor()
@Inject constructor()标记构造函数,告诉 Hilt:这个类无参构造,Hilt 可以自己 new。- 只要构造带
@Inject,不需要写 Module 就能直接提供实例。
Activity 注入
Kotlin
package com.motionguardian.hiltdemo
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject lateinit var user: User
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// super.onCreate 走完之后,user 已经被Hilt赋值完成
}
}
注解说明:
@AndroidEntryPoint:这个 Activity 开启 Hilt 注入能力,Hilt 为此 Activity 生成注入代码。Activity/Fragment/Service 都要加这个注解。@Inject lateinit var user: User:字段注入声明,Hilt 自动赋值。
Kotlin 这里必须
lateinit var,不能用 val,因为是 Hilt 在 super 之后赋值。不能 private。
Hilt的作用

在Hilt中使用Moudle
Kotlin
package com.dongnaoedu.hilt
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ApplicationComponent
import javax.inject.Singleton
@Module
@InstallIn(ApplicationComponent::class)
object AppModule {
@Singleton
@Provides
fun provideUser(): User {
return User()
}
}
逐个注解解释:
@Module标记这个类是 Hilt 模块。模块的作用:告诉 Hilt,这里有创建对象的方法 。 什么时候必须写 Module:要提供的类,不能直接写@Inject constructor()的时候。 比如:第三方 SDK 的类、系统类、构造参数很多、需要传配置。 像刚才简单的User如果可以写@Inject constructor(),就不需要这个 Module。@Provides写在方法上面,这个方法就是造对象的工厂方法。 Hilt 需要 User 对象的时候,就自动执行这个方法,拿到返回的 User 实例。@InstallIn(ApplicationComponent.class)意思:把这个模块安装到全局根容器里面 。ApplicationComponent就是@HiltAndroidApp生成出来的那个全局仓库。 安装在这里,意味着这个模块提供的对象,生命周期和整个 App 进程一致。@Singleton单例注解。 在同一个 Component(这里就是 ApplicationComponent)范围内,Hilt 只会调用一次provideUser(),全程共用同一个 User 对象。
组件与作用域的关系
| Hilt 组件(仓库) | 对应的宿主 | 作用域注解 | 对象生命周期 |
|---|---|---|---|
| ApplicationComponent | Application | @Singleton | 整个 App 进程存活,App 不杀,对象就一直是同一个 |
| ActivityRetainedComponent | ViewModel | @ActivityRetainedScope | 和 ViewModel 同生命周期,配置变更(旋转屏幕)不会销毁;Activity 真正关闭才销毁 |
| ActivityComponent | Activity | @ActivityScoped | Activity 打开时创建,Activity finish 销毁,页面重新打开就换新对象 |
| FragmentComponent | Fragment | @FragmentScoped | Fragment 创建到 Fragment 销毁 |
| ViewComponent | View | @ViewScoped | View 创建到 View 被移除 |
| ViewWithFragmentComponent | 绑定 Fragment 的 View | @ViewScoped | 同上 |
| ServiceComponent | Service | @ServiceScoped | Service 启动到 Service 停止 |
- Component(组件,仓库):容器,是一个存放依赖对象的空间。
@InstallIn就是选择把 Module 放进哪一个仓库。 - Scope(作用域注解):写在
@Provides方法或者@Inject constructor类上面。
Scope 注解必须和 Install 进去的 Component 匹配,不能乱搭配

预定义绑定
预定义绑定 = Hilt 已经提前帮我们写好的 @Provides,我们不用自己写 Module,直接拿来注入。 Hilt 内置把 Android 系统常用对象,提前注册进对应 Component 仓库里了。
| 可以直接注入的类型 | 来自哪个 Component |
|---|---|
| Application | ApplicationComponent |
| Activity | ActivityComponent |
| Context(Activity 上下文) | ActivityComponent |
| Context(Application 上下文) | ApplicationComponent |
| Fragment | FragmentComponent |
| View | ViewComponent |
| Service | ServiceComponent |
有两个 Context 预定义绑定:
- Application Context(全局上下文,不会泄漏):属于
ApplicationComponent - Activity Context(页面上下文,持有 Activity):属于
ActivityComponent
如果直接注入 Context,Hilt 会分不清你要哪一个,这时候就需要 限定符(Qualifier)。
限定符 Qualifier
限定符:给同一个类型打上标签,用来区分同类型多个不同的绑定。
Hilt 自带两个内置限定符:
@ApplicationContext:标记全局 Application 上下文@ActivityContext:标记 Activity 上下文