Dagger2之Kotlin写法

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

内容简介:项目的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写法》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

Dojo权威指南

Dojo权威指南

拉塞尔 / 李松峰、李丽 / 机械工业出版社 / 2009-4 / 79.00元

通过使用Dojo这个工业强度的JavaScript工具箱,我们可以比使用其他任何Ajax框架更高效、更容易地创建JavaScript或Ajax驱动的应用程序和站点。 《Dojo权威指南》向读者展示了如何充分利用Dojo工具箱中包含的大量实用特性,以前所未有的效率开发出功能丰富、响应敏捷的Web应用程序。读者通过《Dojo权威指南》能够学习到创建复杂布局和表单控件(常见于高级桌面应用程序)的技......一起来看看 《Dojo权威指南》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具