专业的编程技术博客社区

网站首页 > 博客文章 正文

Hilt凭什么取代Dagger2成为谷歌官方推荐IOC注入方式

baijin 2024-11-20 12:32:39 博客文章 3 ℃ 0 评论
  • Hilt的基本使用
  • Hilt是怎么通过IOC的方式注入对象和接口的

人生短短数十载,别等生活失序,才焦虑自责;别等老之将至,才追悔莫及。-致自己

本文从定义,用法,由浅到深对Hilt的使用进行讲解,方便各位读者理解。篇幅较长,请耐心阅读。

1 .定义:Hilt 是 Android 的依赖项注入库,可减少在项目中执行手动依赖项注入的样板代码。Hilt 是在 DI 库 Dagger 的基础上构建而成,使用起来比Dagger更简单,更方便。

2 .关系图 :

下面是Hilt各个依懒注入对象之间的关系图。

3 .基础配置:

  • 首先,将 hilt-android-gradle-plugin 插件添加到项目的根级 build.gradle 文件中:
buildscript {
    ...
    dependencies {
        ...
        classpath("com.google.dagger:hilt-android-gradle-plugin:2.38.1")
    }
}
  • 然后在 app/build.gradle 文件中添加以下依赖项:
plugins {
    id 'kotlin-kapt'
    id "dagger.hilt.android.plugin"
}

android {
    ...
        }

dependencies {
    implementation("com.google.dagger:hilt-android:2.38.1")
    kapt("com.google.dagger:hilt-android-compiler:2.38.1")
}

// Allow references to generated code
kapt {
    correctErrorTypes = true
}

4 .常用注解

  • @HiltAndroidApp : 所有使用 Hilt 的应用都必须包含一个带有 @HiltAndroidApp 注解的 Application 类。
  • @AndroidEntryPoint:用来标识需要注入对象的类。
  • @InstallIn:用来表示注入的范围,常用于中间层Moudle。
  • @Module:用来标识中间层Moudle
  • @Provides:用来标识提供注入实例对象的函数。
  • @Binds:用来标识提供注入接口对象的抽象函数。

5 .基本使用

注入对象

(1)定义一个注入对象

class Student {}

(2)在Application中添加@HiltAndroidApp 注解

@HiltAndroidApp
class MainApplication:Application() {
}

(3)创建一个Moudle中间类,用来提供实例对象。

@InstallIn(ActivityComponent::class) // ActivityComponent 只能在activity中使用
@Module //标识为中间层
 object StudentModule {
     @Provides //提供实例对象
     fun  injectStudent():Student{
         return Student()
     }

}

(4)将Student对象注入到Activity中,@Inject修改的对象必须是public属性,否则报错。

@AndroidEntryPoint //标识被注入的类
class MainActivity : AppCompatActivity() {
    //定义被注入的实例
    @Inject lateinit var student:Student 

    @Inject lateinit var student2:Student

    companion object{
        const val TAG = "hiltMainActivity"
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        Log.i(TAG, "onCreate: ${student.javaClass.hashCode()}")
        Log.i(TAG, "onCreate2: ${student2.javaClass.hashCode()}")
    }
}

com.cms.hiltproject I/hiltMainActivity: onCreate: 232833140
com.cms.hiltproject I/hiltMainActivity: onCreate2: 232833140


注入接口

如果注入的是一个接口,在实现上有所不同,我们一起来看一下。

  • 先定义一个People接口,并添加一个speak方法。
interface People {
    fun speak()
}
  • 然后定义一个Man类实现People接口,并且实现speak方法。这里和普通类不同,构造方法上必须添加一个@Inject注解。
class Man :People {
    @Inject
    constructor()
    override fun speak() {
        Log.i(TAG, "speak: Hello Man")
    }
}
  • 定义一个ManModule抽象类,这里和注入实例对象不同,在抽象方法上使用@Binds注解。抽象方法的参数是被注入对象,返回对象是接口。@Binds注解将接口和接口实现类建立绑定关系。
@InstallIn(ActivityComponent::class)
@Module
abstract class PeopleModule {
    @Binds
    abstract fun injectMan(man: Man):People
}
  • 在Activity中可以直接使用People变量调用实现类的方法。
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    @Inject lateinit var student:Student

    @Inject lateinit var student2:Student

    @Inject lateinit var man: Man

    companion object{
        const val TAG = "hiltMainActivity"
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        Log.i(TAG, "Student: ${student.javaClass.hashCode()}")
        Log.i(TAG, "Student2: ${student2.javaClass.hashCode()}")


        Log.i(TAG, "man: ${man.javaClass.hashCode()}")
        man.speak()
    }
}

输出日志:

从输入日志中可以看出,我们再Activity注入的是接口对象,调用的实现类的方法。

讲到这里,相信很多同学已经明白,Hilt框架通过依赖注入的方式,将依懒项与被依懒项隔离开。在实际开发中有很大的作用。能够很好地帮助我们管理代码结构。


还不会的同学赶紧学起来吧,感谢您的阅读,欢迎点赞收藏,您的支持就是小编创作的最大动力!

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表