内容简介:项目的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
- 修饰构造方法
- 修饰变量,在宿主类里,引入要注入的实例
@Module
生产实例的工厂,每一个实例都是通过@Provides修饰的方法提供的
专门解决,不是自己写的类无法在其构造函数上加@Inject的情况
当然自己写的类也可以通过@Provides修饰的方法提供,这样就不会找@Inject的构造函数了
Component
Component是桥梁纽带,是一个接口
功能1:组织依赖关系(链条)
一个Component可以组织多个Module 一个Component还可以组织引入其他的Component
依赖的查找顺序为:先找@Module,如果找到了就停止,如果找不到就去找@Inject
功能2:为宿主类提供Inject方法
@Inject+@Component
所有实例类型全部在我掌控之中 最简单的情况 (不需要Module)
(要注入的实例的类都是自己写的,不需要Module,自己写的类自己用@inject修饰构造方法)
构造方法不带参数
- 注入类的构造方法使用 @Inject
class Apple @Inject constructor(){ var color:String ="red" } 复制代码
-
必须有一个FruitComponent接口,提供一个注入方法
注意:参数必须为要使用对象注入的类
@Component interface FruitComponent { fun inject(activity: MainActivity) } 复制代码
- 通过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来帮忙
两种情况
- 你要注入的实例的类型就不是你自己写的类,无法使用@inject
- 你要注入的实例的类型就是你自己写的类,但是带了一个参数,这个参数类型的类不是你自己写的,无法使用@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写法》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
《裂变:秒懂人工智能的基础课》
王天一 / 电子工业出版社·博文视点 / 2018-6-13 / 59.00元
人工智能是指通过普通计算机程序实现的人类智能技术,这一学科不仅具有非凡的科学意义,对人类自身生存方式的影响也在不断加深。本书作为人工智能领域的入门读物,内容围绕人工智能的核心框架展开,具体包括数学基础知识、机器学习算法、人工神经网络原理、深度学习方法与实例、深度学习之外的人工智能和实践应用场景等模块。本书力图为人工智能初学者提供关于这一领域的全面认识,也为进一步的深入研究建立坚实的基础。一起来看看 《《裂变:秒懂人工智能的基础课》》 这本书的介绍吧!