Hilt使用小结

Hilt是什么?

Hilt是Google工程师找到Dagger2团队专门为Android定制的依赖注入框架,相对于Dagger2,Hilt使用起来更加简单,不需要创建各种Component类;使用依赖注入框架可以让我们的对代码进行解耦,减少代码量的编写。

基本使用

项目配置

  • 配置Hilt gradle插件

    buildscript {
        ...
        dependencies {
            ...
            classpath 'com.google.dagger:hilt-android-gradle-plugin:2.37'
        }
    }
    
  • 配置App/build.gradle:之所以要指定java8是因为Hilt使用到了java8中的一些特性

    apply plugin: 'kotlin-kapt'
    apply plugin: 'dagger.hilt.android.plugin'
    android {
    	compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }
    }
    dependencies {
        implementation 'com.google.dagger:hilt-android:2.37'
        kapt 'com.google.dagger:hilt-android-compiler:2.37'
    }
    
  • 在自定义Application上加上@HiltAndroidApp注解

    @HiltAndroidApp
    class MyApplication : Application() {
    }
    

注入简单对象

  • 创建User类,并在构造方法中加上@Inject注解

    class User @Inject constructor() {
    }
    
  • 在需要注入的类中加上@AndroidEntryPoint注解

    @AndroidEntryPoint
    class HiltActivity : AppCompatActivity() {
    }
    
  • 在需要依赖注入的变量上加上@Inject注解;需要注意的是依赖注入的变量不能是private

    @AndroidEntryPoint
    class HiltActivity : AppCompatActivity() {
    	@Inject
        lateinit var mUser: User
    }
    
  • 如果需要全局单例,则只需要在User对象上加上@Singleton注解

    @Singleton
    class User @Inject constructor() {
    }
    

第三方库中的对象注入

  • 如果需要注入的对象是第三方库中的,我们无法修改它的源码,则需要通过创建Module类提供创建对象的方法;例如需要依赖注入ARouter对象

    @InstallIn(ActivityComponent::class)
    @Module
    class ARouterModule {
    
        @Provides
        fun providerARouter(): ARouter = ARouter.getInstance()
    }
    
    @AndroidEntryPoint
    class HiltActivity : AppCompatActivity() {
    	@Inject
    	lateinit var mARouter: ARouter
    }
    
  • 对第三方对象注入使用单例模式;需要修改Module类,@InstallIn(ActivityComponent::class)改成@InstallIn(SingletonComponent::class) (低版本Hilt中叫ApplicationComponent);然后在创建对象的方法上加上@Singleton注解

    @InstallIn(SingletonComponent::class)
    @Module
    class ARouterModule {
    
        @Singleton
        @Provides
        fun providerARouter(): ARouter = ARouter.getInstance()
    }
    

带参数的对象注入

  • 假如User依赖Car对象,只需要在Car类构造方法添加@inject注解,以告诉Hilt如何创建这个对象即可

    class Car @Inject constructor() {
    	}
    	
    class User @Inject constructor(val car: Car) {
        fun printInfo(){
            Log.i("testHilt","user=$this => car=$car")
        }
    }
    
  • 注入Context:如果某个对象的创建依赖Context,只需要加上@ApplicationContext(注入Application)或者@ActivityContext(注入当前变量所在Activity)即可;也可以不加注解,把依赖的对象改成Application或者Activity也是一样的效果

    • 使用注解方式
      class User @Inject constructor(@ActivityContext val context: Context) {
          fun printInfo(){
              Log.i("testHilt","context=$context")
          }
      }
      class User @Inject constructor(@ApplicationContext val context: Context) {
          fun printInfo(){
              Log.i("testHilt","context=$context")
          }
      }
      
      
    • 使用Application或者Activity方式
      class User @Inject constructor(val context: Application) {
          fun printInfo(){
              Log.i("testHilt","context=$context")
          }
      }
      class User @Inject constructor(val context: Activity) {
          fun printInfo(){
              Log.i("testHilt","context=$context")
          }
      }
      
      

接口注入

  • 为接口类型变量注入实现类,先创建一个接口

    interface IAction {
        fun doAction()
    }
    
  • 创建两个实现类,并在构造方法上加上@Inject以便Hilt可以通过它构建对象

    class RunAction @Inject constructor() : IAction {
    
        override fun doAction() {
            Log.i("testDagger","RunAction")
        }
    }
    class SitAction @Inject constructor() :IAction {
        override fun doAction() {
            Log.i("testDagger","SitAction")
        }
    }
    
  • 由于注入对象时,需要注入的是接口实现,返回的对象类型也是接口,为了区分不同方法创建不同对象实现,需要定义两个不同的自定义注解BindRunAction BindSitAction 名字可以随便取

    @Qualifier
    @Retention(AnnotationRetention.RUNTIME)
    @Target(
        AnnotationTarget.FUNCTION,
        AnnotationTarget.PROPERTY_GETTER,
        AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY
    )
    annotation class BindRunAction
    
    @Qualifier
    @Retention(AnnotationRetention.RUNTIME)
    @Target(
        AnnotationTarget.FUNCTION,
        AnnotationTarget.PROPERTY_GETTER,
        AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY
    )
    annotation class BindSitAction
    
  • 创建Module类提供接口实列的创建

    @InstallIn(ActivityComponent::class)
    @Module
    abstract class ActionModule {
    
        @BindRunAction
        @Binds
        abstract fun bindRunAction(runAction: RunAction): IAction
    
        @BindSitAction
        @Binds
        abstract fun bindSitAction(runAction: SitAction): IAction
    }
    
  • 依赖注入接口实现对象,根据需要添加不同注解以实现注入不同接口实现类

    @AndroidEntryPoint
    class HiltActivity : AppCompatActivity() {
        @BindRunAction
        @Inject
        lateinit var mRunAction: IAction
    
        @BindSitAction
        @Inject
        lateinit var mSitAction: IAction
    }
    
如果您使用的是 Hilt 2.28及以上版本,则可以不需要在 AndroidManifest.xml 文件中的 Application 标签添加 AndroidEntryPoint 注解,而是在 HiltApplication 中添加 @HiltAndroidApp 注解即可。 至于如何在代码中使用 Hilt 进行依赖注入,您可以使用 @Inject 注解来标记需要注入的依赖,同时在需要使用该依赖的地方使用 @Inject 注解进行注入。此外,您还可以通过 @Module 和 @Provides 注解来自定义依赖的注入行为。 例如,以下是一个使用 Hilt 进行依赖注入的示例代码: ```java @AndroidEntryPoint public class MyActivity extends AppCompatActivity { @Inject MyDependency myDependency; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 使用注入的依赖 myDependency.doSomething(); } } @Module @InstallIn(ActivityComponent.class) public class MyModule { @Provides MyDependency provideMyDependency() { return new MyDependencyImpl(); } } ``` 在上述代码中,我们使用 @AndroidEntryPoint 标注了 MyActivity,表示该 Activity 会使用 Hilt 进行依赖注入。通过 @Inject 注解标记了 MyDependency 字段,表示需要注入 MyDependency 类型的依赖。在 MyModule 中使用 @Provides 注解提供了 MyDependency 的实例。在 MyActivity 中,我们直接使用注入的 MyDependency 实例来调用其方法。 需要注意的是,上述代码是基于 Hilt 2.28及以上版本进行的示例。如果您使用的是旧版本的 Hilt,可能需要做出一些调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值