Dagger2之Kotlin写法

栏目: IOS · 发布时间: 6年前

内容简介:项目的gradlemodule的gradle生产实例的工厂,每一个实例都是通过@Provides修饰的方法提供的

项目的gradle

buildscript {
ext.dagger_version = '2.11'
}
复制代码

module的gradle

//多模块项目,这个必须在使用到dagger2的所有moudle里都配置
apply plugin: 'kotlin-kapt'

dependencies {
    //dagger2,这个可以写在BaseMoudle里
    api "com.google.dagger:dagger:$dagger_version"
    //多模块项目,这个必须在使用到dagger2的所有moudle里都配置
    kapt "com.google.dagger:dagger-compiler:$dagger_version"
}
复制代码

概念

@Inject

  1. 修饰构造方法
  2. 修饰变量,在宿主类里,引入要注入的实例

@Module

生产实例的工厂,每一个实例都是通过@Provides修饰的方法提供的

专门解决,不是自己写的类无法在其构造函数上加@Inject的情况

当然自己写的类也可以通过@Provides修饰的方法提供,这样就不会找@Inject的构造函数了

Component

Component是桥梁纽带,是一个接口

功能1:组织依赖关系(链条)

一个Component可以组织多个Module 一个Component还可以组织引入其他的Component

依赖的查找顺序为:先找@Module,如果找到了就停止,如果找不到就去找@Inject

功能2:为宿主类提供Inject方法

@Inject+@Component

所有实例类型全部在我掌控之中 最简单的情况 (不需要Module)

(要注入的实例的类都是自己写的,不需要Module,自己写的类自己用@inject修饰构造方法)

构造方法不带参数

  1. 注入类的构造方法使用 @Inject
class Apple @Inject constructor(){
    var color:String ="red"
}
复制代码
  1. 必须有一个FruitComponent接口,提供一个注入方法

    注意:参数必须为要使用对象注入的类

@Component
interface FruitComponent {
    fun inject(activity: MainActivity)
}
复制代码
  1. 通过inject注入所有对象,@Inject使用注入对象
class MainActivity : AppCompatActivity() {
    @Inject
    lateinit var apple: Apple//注入实例

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        DaggerFruitComponent.builder().build().inject(this)//必须注入一下
        tv1.setOnClickListener {
            rx1()
        }
    }

    private fun rx1() {
        toast(apple.color)

    }
}
复制代码

构造方法带参数

(但是所带参数的构造函数,也可以被@Inject修饰,即所带参数的类型的类也是自己写的)

class Apple @Inject constructor(val knife: Knife) {
    var color: String = "red"
}
复制代码
class Knife @Inject constructor() {
    var name: String = "小刀"
}
复制代码
@Component
interface FruitComponent {
    fun inject(activity: MainActivity)
}
复制代码
class MainActivity : AppCompatActivity() {
    @Inject
    lateinit var apple: Apple
    @Inject
    lateinit var knife: Knife
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        DaggerFruitComponent.builder().build().inject(this)
        tv1.setOnClickListener {
            rx1()
        }
    }

    private fun rx1() {
        Log.e("CCC",knife.name)
        Log.e("CCC",apple.color)

    }
}
复制代码

@Inject+@Component+@Module(含@Provides)

有些实例类型,我无法掌控

别慌!@Module来帮忙

两种情况

  1. 你要注入的实例的类型就不是你自己写的类,无法使用@inject
  2. 你要注入的实例的类型就是你自己写的类,但是带了一个参数,这个参数类型的类不是你自己写的,无法使用@inject

情况一

@Module
class SecondModule {
    @Provides
    fun provideString():String{
        return  "我是String,你能在我的构造方法上加@inject吗?是的,你不能!"
    }
}
复制代码
@Component(modules = [SecondModule::class])
interface SecondComponent {
    fun  inject(activity:MainActivity)
}
复制代码
class MainActivity : AppCompatActivity() {

    @Inject
    lateinit var s: String


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        DaggerSecondComponent.builder().build().inject(this)//注入
        tv1.setOnClickListener {
            rx1()
        }
    }

    private fun rx1() {
        Log.e("CCC", s)
    }
}

复制代码

情况二

Person 是我自己写的类,我可以在它构造方法上面加@inject,但是他有一个参数是String,你要提供Person对象就必须提供Person所需要的所有参数,我们无法在String上加@inject

class Person @Inject constructor(var name: String){
    
}
复制代码
@Module
class SecondModule {
    @Provides
    fun provideString():String{
        return  "我是为Person提供name的,但是我是String,你能在我的构造方法上加@inject吗?是的,你不能!"
    }
}
复制代码
@Component(modules = [SecondModule::class])
interface SecondComponent {
    fun  inject(activity:MainActivity)
}
复制代码
class MainActivity : AppCompatActivity() {

    @Inject
    lateinit var person: Person

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        DaggerSecondComponent.builder().build().inject(this)
        tv1.setOnClickListener {
            rx1()
        }
    }

    private fun rx1() {
        Log.e("CCC", person.name)
    }
}
复制代码

SecondComponet依赖其他的ThirdComponet

1.先准备第一个ThirdComponet,他一会要被SecondComponet依赖

class Cat @Inject constructor(var age: Int)
复制代码
@Module
class ThirdMoudle {
//    这里直接提供了Cat的实例,而不是只是提供一个age(类似上面Person的name)
//    直接提供实例,就不用写提供age实例的provides方法了
    @Provides
    fun provideCat():Cat{
        return Cat(1)
    }
}
复制代码
<!--好多坑,看注释-->
@Component(modules = [ThirdMoudle::class])
interface ThirdComponet {
//    ★因为这个ThirdComponet要被SceondComponent依赖,这里必须提供一个方法,不然报错
//    ★如果没有Componet依赖ThirdComponet,这里可以不写
    fun provideCat():Cat
    //fun inject(activity:Activity)
    //★如果ThirdComponet没有要注入的类,这里不要写inject也行,但是写的话千万不能同SecondComponet所注入的类一样,会报错
}
复制代码

2. 看第二个SecondComponent的写法

class Person @Inject constructor(var name: String)
复制代码
@Module
class SecondModule {
    @Provides
    fun provideString():String{
        return  "我是为Person提供name的,
        但是我是String,你能在我的构造方法上加@inject吗?是的,你不能!"
    }
}
复制代码
@Component(modules = [SecondModule::class]
    ,dependencies = [ThirdComponet::class])
    //★dependencies依赖ThirdComponet
interface SecondComponent {
    fun  inject(activity:MainActivity)
}
复制代码

3. 注入到MainActivity使用

class MainActivity : AppCompatActivity() {

    @Inject
    lateinit var person: Person
    @Inject
    lateinit var cat: Cat

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val thirdComponet = DaggerThirdComponet.builder().build()

        DaggerSecondComponent.builder()
            .thirdComponet(thirdComponet)//★注意这里传入thirdComponet
            .build().inject(this)
        tv1.setOnClickListener {
            rx1()
        }
    }

    private fun rx1() {
        Log.e("CCC", person.name)
        Log.e("CCC", "${cat.age}")
    }
}
复制代码

以上所述就是小编给大家介绍的《Dagger2之Kotlin写法》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Charlotte's Web

Charlotte's Web

E. B. White / Scholastic / 2004 / USD 0.01

This is the tale of how a little girl named Ferm, with the help of a friendly spider, saved her pig, Wilbur, from the usual fate of nice fat little pigs.一起来看看 《Charlotte's Web》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具