这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战
添加依赖
implementation 'com.google.dagger:dagger:2.37'
kapt 'com.google.dagger:dagger-compiler:2.37'
一:提供实例
一:通过构造方法
通过在类的构造方法中添加@Inject
注解
class User @Inject constructor(){}
二:通过dagger模块注入
模块注入适用于第三方库,不方便添加在构造函数添加@Inject
注解的情况。这里用创建Student
类模拟。
class Student {
}
@Module
class StudentModule {
@Provides
fun provideStudent() = Student()
}
二:提供组件容器
@Component
interface ApplicationComponent {
//要注入的目标activity
fun inject(activity: MainActivity)
}
如果要添加容器(modules
),可以在@Component
添加modules
参数,例如上面的StudentModule
。
@Component(modules = [StudentModule::class])
interface ApplicationComponent {
fun inject(activity: MainActivity)
}
三:在目标Activity中使用
class MainActivity : AppCompatActivity() {
//构造函数注入
@Inject
lateinit var user: User
//modules方式注入
@Inject
lateinit var student: Student
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
DaggerApplicationComponent.create().inject(this)
Log.i("tag", "onCreate: $user")
Log.i("tag", "onCreate: $student")
}
}
其他
作用域
使用作用域注解,可以将某个对象的生命周期限定为其组件的生命周期。这样也就意味着,在作用域范围内,使用到的是同一个实例。
@Singleton
是Dagger
提供的一种默认的作用域注解,其意义表示一个单例对象,这里的单例表示的是在组件容器内。
作用域注解使用在@Inject
、@Provides
、@Binds
、@Module
、@Component
注解上,表示其产生作用的范围。
注意:
- 如果实体添加了作用域注解,那么组件必须也添加一样的注解,不然编译不通过,报错。
例如在module
的实体中的provideStudent
方法添加@Singleton
注解
@Module
class StudentModule {
@Singleton
@Provides
fun provideStudent() = Student()
}
那么组件ApplicationComponent
也必须添加相对应的注解
//module中添加了@Singleton,那么这里也必须添加@Singleton
@Singleton
@Component(modules = [StudentModule::class])
interface ApplicationComponent {
fun inject(activity: MainActivity)
fun inject(activity: SecondActivity)
}
这里的@Singleton
意思是,在同一ApplicationComponent
实例中保持单例。
-
组件添加作用域注解,
module
里面的实体不一定需要强制添加作用域注解。不添加时使用默认作用域注解。 -
单例只是针对在同一个组件来说,在上面的例子中,
modules
和ApplicationComponent
添加了@Singleton
,那么在MainActivity
中是单例的,如果在SecondActivity
中也注入student
,那么就是另外一个实例,因为通过
DaggerApplicationComponent.create().inject(this)
注入会生成新的ApplicationComponent
组件实例,所以说作用域注解,是将某个对象的生命周期限定为其组件的生命周期的。
组件依赖
在同一个Activity
做两个组件做注入动作是不可以的。
@Singleton
@Component(modules = [StudentModule::class])
interface ApplicationComponent {
fun inject(activity: MainActivity)
fun inject(activity: SecondActivity)
}
@Component
interface UserComponent {
fun inject(activity: MainActivity)
}
例如ApplicationComponent
和UserComponent
同时声明注入MainActivity
是直接编译不通过的。