hilt依赖注入 他应该满足,只要应用程序存在,那么依赖项就一直存在,并且保持单例模式
添加依赖项 首先,将 hilt-android-gradle-plugin
插件添加到项目的根级 build.gradle
文件中:
1 2 3 4 plugins { ... id("com.google.dagger.hilt.android" ) version "2.44" apply false }
然后,应用 Gradle 插件并在 app/build.gradle
文件中添加以下依赖项:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 plugins { id("com.android.application" ) id("org.jetbrains.kotlin.android" ) kotlin("kapt" ) id("com.google.dagger.hilt.android" ) ) dependences{ implementation("com.google.dagger:hilt-android:2.44" ) kapt("com.google.dagger:hilt-android-compiler:2.44" ) implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2" ) } kapt { correctErrorTypes = true }
注册Activity,Application Hilt 应用类 所有使用 Hilt 的应用都必须包含一个带有 @HiltAndroidApp
注解的 Application
类。
@HiltAndroidApp
会触发 Hilt 的代码生成操作,生成的代码包括应用的一个基类,该基类充当应用级依赖项容器。(需要在Manifest中注册 )
1 2 @HiltAndroidApp class ExampleApplication : Application () { ... }
将依赖项注入 Android 类 在 Application
类中设置了 Hilt 且有了应用级组件后,Hilt 可以为带有 @AndroidEntryPoint
注解的其他 Android 类提供依赖项:
1 2 @AndroidEntryPoint class ExampleActivity : AppCompatActivity () { ... }
Hilt 目前支持以下 Android 类:
Application
(通过使用 @HiltAndroidApp
)
ViewModel
(通过使用 @HiltViewModel
)
Activity
Fragment
View
Service
BroadcastReceiver
singleton component vs singleton annotation? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Module @InstallIn(SingletonComponent::class) object AppModule { @Provides @Singleton fun provideMyApi () : MyApi { return Retrofit.Builder() .baseUrl("https://zfxt.top" ) .build() .create(MyApi::class .java) } }
viewModel 构建一个viewModel带参数时,我们通常需要使用到factory去构建,不然将会很难实现其功能。如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class MyViewModel ( private val repository: MyRepository ):ViewModel() { } @HiltViewModel class MyViewModel @Inject constructor ( private val repository: MyRepository ):ViewModel() { }
AppModule 对于AppModule中相互调用,只需要添加其参数即可自动识别到
对于Module而言,他会根据返回的类型来判断注入方式。如果你对某一个类型有多个返回方法就可能导致程序奔溃,例如你定义了两个providerString1
和provideString2
就会导致程序奔溃
因此,我们需要通过@Named
来区分同一类型的对象如何导入
如下所示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 @Module @InstallIn(SingletonComponent::class) object AppModule { @Provides @Singleton fun provideMyApi () : MyApi { return Retrofit.Builder() .baseUrl("https://zfxt.top" ) .build() .create(MyApi::class .java) } @Provides @Singleton fun providerMyRepository (api:MyApi ,app:Application ,@Named("hello1" ) hello:String ) : MyRepository { return MyRepositoryImpl(api,app) } @Provides @Singleton @Named("hello1" ) fun providerString1 () ="Hello 1" @Provides @Singleton @Named("hello2" ) fun providerString2 () ="Hello 2" }
Binding方式 我们可以不适用@Provider的方式提供,而是通过构建一个抽象类和抽象函数来实现,
如下:
首先为我们的实现类注释@Inject
的构造函数方法
1 class MyRepositoryImpl @Inject constructor (...)
然后创建一个新的抽象类
1 2 3 4 5 6 7 8 9 10 @Module @InstallIn(SingletonComponent::class) abstract class RepositoryModule { @Binds @Singleton abstract fun bindMyRepository ( myRepository: MyRepositoryImpl ) :MyRepository}
这样子就算实现功能了,他的使用场景通常是无法通过构造函数来构建的时候,在我们使用service的时候,我们就不能通过创建的方式来导入repository。因此我们用@Inject
加上Binding的方法实现注入功能
1 2 3 4 5 6 7 @AndroidEntryPoint class MyService :Service (){@Inject liteinit var repository:MyRepository override fun onBind (po:Intent ?) :IBinder?return null }
Lazy Injection 他会延迟注入,只有在对象被使用到的时候才去注入,
他的使用方法为在类型外包一层Lazy<>
即可:如
1 2 3 4 @HiltviewModel class MyViewModel @Inject constructor (private val repository:Lazy<MyRepository>)ViewModel(){