100% 可以!!!
普通类(不是 ViewModel)完全能用 Hilt 依赖注入!
我给你用最简单、最确定的话讲清楚:
一、结论(超级重要)
不管是不是 ViewModel不管是不是 Activity不管是不是 Fragment只要是个类,都能用 @Inject 注入!
kotlin
kotlin
// 普通类,不是 ViewModel → 照样可以注入!
class TravelManager @Inject constructor(
private val mApiService: Api,
private val gson: Gson
) {
// 随便用
}
✅ 完全支持 ✅
二、那 ViewModel 和普通类的区别是什么?
1. 普通类
只需要在**构造函数上加 @Inject**别的什么都不用加!
kotlin
kotlin
class 普通类 @Inject constructor(
private val api: Api,
private val gson: Gson
)
2. ViewModel 类
必须加 **@HiltViewModel**因为它是特殊的生命周期类
kotlin
less
@HiltViewModel
class ViewModel类 @Inject constructor(
private val api: Api
) : ViewModel()
三、普通类注入后,怎么用?
方式 1:在别的被注入的类里直接用(最常用)
kotlin
kotlin
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
// 直接注入普通类(TravelManager支持注入必须写@Inject constructor())
@Inject
lateinit var travelManager: TravelManager
}
方式 2:在 ViewModel 里用
kotlin
less
@HiltViewModel
class MyViewModel @Inject constructor(
private val travelManager: TravelManager // 普通类直接注入
) : ViewModel()
四、Hilt 会自动创建普通类吗?
会!!!
你写:
kotlin
kotlin
class A @Inject constructor()
class B @Inject constructor()
class C @Inject constructor(
val a: A,
val b: B
)
Hilt 会自动创建 A → 自动创建 B → 自动传给 C你完全不用管!
五、你现在的代码改成普通类,完全正确
kotlin
kotlin
// 普通类,不是 ViewModel
class TravelManager @Inject constructor(
private val mApiService: Api,
private val gson: Gson
) {
// 正常写逻辑
}
✅ 能运行✅ 能注入✅ 能使用
六、超级总结(背会)
- 普通类 + @Inject 构造函数 = 支持注入
- ViewModel + @HiltViewModel + @Inject = 支持注入
- Activity/Fragment + @AndroidEntryPoint = 支持注入
- 所有类都能被 Hilt 管理
- 不需要继承任何类!
七、普通类被别人注入(重点)
这种类,想让 Hilt 注入,只需要加一个注解: @Inject constructor()
kotlin
kotlin
class TravelManager @Inject constructor()
就这一步,完事。
2. 然后你在 Activity 里就能直接用
kotlin
kotlin
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject
lateinit var travelManager: TravelManager
}
✅ 直接运行,不会报错
✅ 不需要 Module
✅ 不需要 @Provides
✅ 不需要继承任何东西
3. 为什么可以?
Hilt 看到:
TravelManager构造是@Inject- 没有参数→ Hilt 直接帮你 new 一个实例 注入进去。
4. 超级精简总结
- 空类
class A→ 加@Inject constructor()→ 就能被@Inject到处用
5. 完整最小示例(复制就能跑)
kotlin
kotlin
// 普通空类,加个 @Inject 构造
class TravelManager @Inject constructor() {
fun sayHi() = "我是被 Hilt 注入的!"
}
kotlin
kotlin
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject lateinit var travelManager: TravelManager
override fun onCreate(...) {
super.onCreate(...)
println(travelManager.sayHi())
}
}
八、什么时候用 @Inject 构造,什么时候必须写 Module @Provides?
1、 什么时候用:@Inject constructor()
适用场景
- 你自己写的类
- 构造方法里的参数,Hilt 能找到(要么也是 @Inject,要么有 @Provides)
- 不需要复杂配置、不需要 builder 模式、不需要动态参数
写法
kotlin
kotlin
class TravelManager @Inject constructor(
private val api: Api,
private val gson: Gson
)
一句话判断
这个类是我写的,我能改它的构造 → 用 @Inject 构造!
2、 什么时候必须用:@Module + @Provides
适用场景(满足任意一条就必须用)
- 类不是你写的(第三方库:OkHttp、Retrofit、Gson、Glide、Room...)
- 构造方法私有 ,你不能直接
new - 需要复杂构建(builder 模式、拦截器、配置、证书)
- 需要动态传参(Context、BuildConfig、URL 等)
- 接口 / 抽象类(无法直接实例化)
写法
kotlin
less
@Module
@InstallIn(SingletonComponent::class)
object NetModule {
// 第三方类 → 必须 Provides
@Provides
fun provideGson(): Gson {
return GsonBuilder()
.setLenient()
.create()
}
}
一句话判断
这个类我改不了源码 / 要复杂配置 → 必须写 @Provides!
九、 终极口诀(背会这 2 句就永远不会错)
- 自己写的类 → 加
@Inject constructor() - 别人写的类 / 需要配置 → 写
@Module + @Provides
一张表彻底分清
表格
| 情况 | 用啥 | 示例 |
|---|---|---|
| 自己写的普通类 | @Inject constructor() |
class UserManager @Inject constructor() |
| 自己写的类,需要 Api | @Inject constructor(api: Api) |
自动注入 |
| Gson / OkHttp / Retrofit | @Provides |
第三方,必须手动构建 |
| 接口(Api Service) | @Provides |
retrofit.create(api::class.java) |
| 需要 Context 的类 | @Provides |
provideContext(application) |
回到你最开始的代码,完美对应
kotlin
kotlin
// 自己写的 → @Inject 构造
class TravelManager @Inject constructor(
private val api: Api, // 来自 Provides
private val gson: Gson // 来自 Provides
)
// 第三方 → 必须 Provides
@Module
object NetModule {
@Provides fun provideApi...
@Provides fun provideGson...
}