一、Hilt 2.44 完整配置(必做)
1. 项目根 build.gradle/build.gradle.kts
gradle
arduino
// Groovy
buildscript {
dependencies {
classpath "com.google.dagger:hilt-android-gradle-plugin:2.44"
}
}
2. App 模块 build.gradle
gradle
bash
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin' // 必须
}
dependencies {
// Hilt
implementation "com.google.dagger:hilt-android:2.44"
kapt "com.google.dagger:hilt-android-compiler:2.44"
}
3. 自定义 Application(必须)
kotlin
kotlin
import android.app.Application
import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp // 核心:触发Hilt初始化
class MyApp : Application()
4. AndroidManifest.xml(必须)
只需要指定你的 Application:
xml
ini
<application
android:name=".MyApp" <!-- 必须 -->
...>
</application>
二、你写的 NetModule 正确用法(回顾)
kotlin
kotlin
@Module
@InstallIn(SingletonComponent::class) // 全局单例
object NetModule {
@Provides
fun provideOkHttpClient(): OkHttpClient {
return OkHttpClient.Builder()
.addInterceptor(...)
.build()
}
@Provides
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("https://xxx")
.build()
}
@Provides
fun provideApiService(retrofit: Retrofit): Api {
return retrofit.create(Api::class.java)
}
}
@Module:告诉 Hilt 这是提供依赖的模块@InstallIn(SingletonComponent::class):生命周期 = 整个 App@Provides:方法用来创建对象,Hilt 自动调用、自动传参
三、ViewModel 注入(你之前的代码)
1、依赖单个:
kotlin
kotlin
import androidx.lifecycle.ViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
@HiltViewModel // 必须
class TravelViewModel @Inject constructor(
private val api: Api // Hilt 自动注入 Api
) : ViewModel() {
}
- Activity / Fragment 必须加
@AndroidEntryPoint
kotlin
kotlin
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
// 直接用
private val viewModel: TravelViewModel by viewModels()
}
2、依赖多个:
kotlin
less
@HiltViewModel
class TravelViewModel @Inject constructor(
private val mApiService: Api, // 来自 NetModule
private val mGson: Gson, // 来自 SingletonModule
private val mUserRepository: Repository // 也能加
) : ViewModel()
3、 为什么可以?
因为:
- 每一个 @Provides 方法,Hilt 都会单独管理
- 你在构造函数里写多少个依赖,Hilt 就自动去找多少个
- 它们互不干扰
- 顺序无关紧要
你有两个 Module:
kotlin
less
@Module
@InstallIn(SingletonComponent::class)
object NetModule {
@Provides fun providerApiService(): Api { ... }
@Provides fun providerOkHttpClient(): OkHttpClient { ... }
}
@Module
@InstallIn(SingletonComponent::class)
object SingletonModule {
@Provides fun providerGson(): Gson { ... }
}
ViewModel 构造函数:
kotlin
less
@Inject constructor(
api: Api, // Hilt → 找 NetModule.providerApiService()
gson: Gson // Hilt → 找 SingletonModule.providerGson()
)
四、Hilt 2.44 常用注解速记(背会)
@HiltAndroidApp→ Application(必须)@AndroidEntryPoint→ Activity/Fragment/Service@HiltViewModel→ ViewModel@Inject→ 构造 / 字段注入@Module+@InstallIn(xxxComponent::class)→ 提供第三方依赖(如 Retrofit、OkHttp、Room)@Provides→ 模块内提供实例
五、你现在的代码是否正确?
你贴的:
kotlin
less
@Module
@InstallIn(SingletonComponent::class)
object NetModule {
@Provides fun providerOkHttpClient()...
@Provides fun providerRetrofit()...
@Provides fun providerApiService()...
}
@HiltViewModel
class TravelViewModel @Inject constructor(private val api: Api)
六、网络请求详细分析:
kotlin
package com.fmt.mvi.learn.di
import com.fmt.mvi.learn.BuildConfig
import com.fmt.mvi.learn.gobal.ConfigKeys
import com.fmt.mvi.learn.gobal.Configurator
import com.fmt.mvi.learn.net.Api
import com.orhanobut.logger.Logger
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
@Module
@InstallIn(SingletonComponent::class)
object NetModule {
@Provides
fun providerOkHttpClient(): OkHttpClient {
return OkHttpClient.Builder()
.apply {
if (BuildConfig.DEBUG) {
addInterceptor(HttpLoggingInterceptor {
Logger.d(it)
}.setLevel(HttpLoggingInterceptor.Level.BODY))
}
}
.build()
}
@Provides
fun providerRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(Configurator.getConfiguration<String>(ConfigKeys.API_HOST))
.build()
}
@Provides
fun providerApiService(retrofit: Retrofit): Api {
return retrofit.create(Api::class.java)
}
}
1、 核心结论(最重要)
你只需要写:
kotlin
kotlin
class TravelViewModel @Inject constructor(
private val mApiService: Api
): ViewModel(){}
Hilt 就会 自动、自动、自动 按这个顺序执行:
- providerOkHttpClient()
- providerRetrofit(okHttpClient)
- providerApiService(retrofit)
你不用管,完全不用调用!
我给你拆开讲,一看就懂
第一步:你要 Api
kotlin
kotlin
@Inject constructor(
private val mApiService: Api
)
Hilt 听到了:哦!你要 Api 实例!
第二步:Hilt 去找谁能提供 Api
kotlin
kotlin
@Provides
fun providerApiService(retrofit: Retrofit): Api {
return retrofit.create(Api::class.java)
}
Hilt 找到了:这个方法能提供 Api!
但是 Hilt 发现:这个方法需要 Retrofit!
第三步:Hilt 去找 Retrofit
kotlin
kotlin
@Provides
fun providerRetrofit(okHttpClient: OkHttpClient): Retrofit {
...
}
Hilt 找到了 Retrofit,但发现:这个方法需要 OkHttpClient!
第四步:Hilt 去找 OkHttpClient
kotlin
kotlin
@Provides
fun providerOkHttpClient(): OkHttpClient {
...
}
Hilt 找到了:这个方法不需要参数!直接执行!
最终执行顺序(自动)
- 执行
providerOkHttpClient()→ 得到okHttpClient - 把 okHttpClient 传给
providerRetrofit(okHttpClient)→ 得到retrofit - 把 retrofit 传给
providerApiService(retrofit)→ 得到api - 把
api自动传给你的 ViewModel
plaintext
ViewModel 要 Api
→ 需要 Retrofit
→ 需要 OkHttp
→ 先创建 OkHttp
→ 再创建 Retrofit
→ 再创建 Api
→ 塞给 ViewModel
生活比喻(秒懂)
你(ViewModel)说:我要吃饭(Api)
Hilt 自动做:
- 先去买菜(OkHttp)
- 再洗菜切菜(Retrofit)
- 最后炒菜(Api)
- 把菜端给你
你全程不用动手!
你真正需要写的代码只有一行
kotlin
kotlin
@Inject constructor(private val api: Api)
剩下的全部自动完成!
超级总结(背会)
- Hilt 会自动解析依赖关系
- 你要 Api → 自动找 Retrofit → 自动找 OkHttp
- 自动按顺序创建对象
- 你完全不用调用任何 providerXXX 方法