内容简介:项目的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写法》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Pro CSS and HTML Design Patterns
Michael Bowers / Apress / April 23, 2007 / $44.99
Design patterns have been used with great success in software programming. They improve productivity, creativity, and efficiency in web design and development, and they reduce code bloat and complexit......一起来看看 《Pro CSS and HTML Design Patterns》 这本书的介绍吧!