dagger2学习之旅

469 阅读2分钟

这是我参与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")
    }
}

其他

作用域

使用作用域注解,可以将某个对象的生命周期限定为其组件的生命周期。这样也就意味着,在作用域范围内,使用到的是同一个实例。

@SingletonDagger提供的一种默认的作用域注解,其意义表示一个单例对象,这里的单例表示的是在组件容器内。

作用域注解使用在@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里面的实体不一定需要强制添加作用域注解。不添加时使用默认作用域注解。

  • 单例只是针对在同一个组件来说,在上面的例子中,modulesApplicationComponent添加了@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)
}

例如ApplicationComponentUserComponent同时声明注入MainActivity是直接编译不通过的。