Hilt使用小结

Posted guangdeshishe

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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(RetentionPolicy.RUNTIME)
    @Target(
        AnnotationTarget.FUNCTION,
        AnnotationTarget.PROPERTY_GETTER,
        AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY
    )
    annotation class BindRunAction
    
    @Qualifier
    @Retention(RetentionPolicy.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使用小结的主要内容,如果未能解决你的问题,请参考以下文章

Android依赖注入框架Hilt基本使用

Android Dagger-Hilt 依赖注入

带有泛型的 Dagger Hilt 缺失/绑定接口

Android Hilt 使用

Android Hilt 使用

Android Hilt 使用