依赖
项目的gradle
buildscript {
ext.dagger_version = '2.11'
}123
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"
}123456789
概念
@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"
}123
必须有一个FruitComponent接口,提供一个注入方法
注意:参数必须为要使用对象注入的类
@Component
interface FruitComponent {
fun inject(activity: MainActivity)
}1234
通过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)
}
}12345678910111213141516171819
构造方法带参数
(但是所带参数的构造函数,也可以被@Inject修饰,即所带参数的类型的类也是自己写的)
class Apple @Inject constructor(val knife: Knife) {
var color: String = "red"
}123
class Knife @Inject constructor() {
var name: String = "小刀"
}123
@Component
interface FruitComponent {
fun inject(activity: MainActivity)
}1234
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)
}
}123456789101112131415161718192021
@Inject+@Component+@Module(含@Provides)
有些实例类型,我无法掌控
别慌!@Module来帮忙
两种情况
你要注入的实例的类型就不是你自己写的类,无法使用@inject
你要注入的实例的类型就是你自己写的类,但是带了一个参数,这个参数类型的类不是你自己写的,无法使用@inject
情况一
@Module
class SecondModule {
@Provides
fun provideString():String{
return "我是String,你能在我的构造方法上加@inject吗?是的,你不能!"
}
}1234567
@Component(modules = [SecondModule::class])
interface SecondComponent {
fun inject(activity:MainActivity)
}1234
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)
}
}123456789101112131415161718192021
情况二
Person 是我自己写的类,我可以在它构造方法上面加@inject,但是他有一个参数是String,你要提供Person对象就必须提供Person所需要的所有参数,我们无法在String上加@inject
class Person @Inject constructor(var name: String){
}123
@Module
class SecondModule {
@Provides
fun provideString():String{
return "我是为Person提供name的,但是我是String,你能在我的构造方法上加@inject吗?是的,你不能!"
}
}1234567
@Component(modules = [SecondModule::class])
interface SecondComponent {
fun inject(activity:MainActivity)
}1234
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)
}
}