什么是IOC
IOC是Inversion of Control的缩写,翻译为控制反转,是面向对象编程中的一种设计原则,可以用来降低代码之间的耦合度。
既然IOC是控制反转,那么是哪些方面的控制被反转了呢?其实是获得依赖对象的过程被反转了,控制被反转之后,获得依赖对象的过程由自身管理变为了由IOC容器主动注入。
因此IOC中最常见的方式叫做依赖注入(Dependency Injection,简称DI),所谓依赖注入,就是由IOC容器在运行期间,动态地将某种依赖关系注入到对象之中。
Android 中应用
Android中应用最常见的有ButterKnife、Dagger2等,用来实现对象和事件的注入。普遍的实现方式是使用自定义注解来做标记,然后可以使用反射或者java动态代理来生成依赖注入的代码,但考虑到运行时反射的效率低问题转而使用注解处理器APT在编译时生成注入代码。
Hilt 是什么
Hilt 是 Android 的依赖注入库,其实是基于 Dagger 。可以说 Hilt 是专门为 Andorid 打造的。
Hilt 创建了一组标准的 组件和作用域。这些组件会自动集成到 Android 程序中的生命周期中。在使用的时候可以指定使用的范围,事情作用在对应的生命周期当中。
Hilt支持的Android组件
其中没有contentProvider 因为contentProvider的生命周期比较特殊,他是在Application的onCreate之前就已经完成初始化了 ,而hlit实在Application中完成初始化的。
使用 Hilt
- 在项目的build.gradle中添加引用
classpath 'com.google.dagger:hilt-android-gradle-plugin:2.28-alpha'
- 在App的build.gradle中添加plugin的引用和依赖:
apply plugin: 'kotlin-kapt'
apply plugin: 'dagger.hilt.android.plugin'
dependencies {
implementation "com.google.dagger:hilt-android:2.28-alpha"
kapt "com.google.dagger:hilt-android-compiler:2.28-alpha"
}
- Hlit初始化
所有使用Hilt的项目都需要包含一个带有@HiltAndroidApp注释的Application类.
@HiltAndroidApp会触发Hilt代码生成,生成的代码包含应用的一个基类,该基类充当应用级依赖项容器。
@HiltAndroidApp
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
}
}
只有 Application 这个入口点是使用 @HiltAndroidApp 注解来声明的。其他的所有入口点,都是用 @AndroidEntryPoint 注解来声明的。
Hilt为何要增加@HiltAndroidApp注解
1:将ApplicationContextModule添加至应用组件中,获取应用组件applicationContext
2:自动实现了依赖注入,免去了类似Dagger的手动调用
注意点:
1.如果使用 @AndroidEntryPoint 注解 Android 类,还必须注解依赖他的 Android 类;
2.如果给 fragment 使用 @AndroidEntryPoint 后,则还需要给 fragmet 依赖的 Activity 依赖@AndroidEntryPoint ,否则会出现异常;
3.@AndroidEntryPoint 不能以写在抽象类上;
示例:将Http请求对象HttpHelper注入到MainActivity中
提供一个需要注入的类,加上Module标签。声明InstallIn标签声明该对象要注入到什么组件中,比如ActivityComponent、ApplicationComponent等。InstallIn,就是安装到的意思。那么 @InstallIn(ActivityComponent::class),就是把这个模块安装到 Activity 组件当中,而且也只能在Activity 中只用。
@InstallIn(ActivityComponent::class)
@Module
class HttpModule {
@Provides
fun getHttpObject(): HttpModule {
return HttpModule()
}
}
在需要注入的Activity中加入AndroidEntryPoint注解,在httpModule加入Inject注入注解。这样就能直接在该Activity中获取对象实例了。
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject
lateinit var httpModule: HttpModule
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.i("minfo", httpModule.hashCode().toString())
}
}
@AndroidEntryPoint注解了Activity之后Hilt帮我们做了什么?
Hilt自动帮我们生成了一个继承自AppCompatActivity的名称为Hilt_MainActivity.java类。
1:在onCreate方法中通过injectMainActivity将我们的MainActivity注入到了ActivityComponent组件中
2:提供了一个ViewModelProvider.Factory工厂类。
组件生命周期
Hilt 会按照相应 Android 类的生命周期自动创建和销毁生成的组件类的实例。
网友评论