項目的gradleapi
buildscript {
ext.dagger_version = '2.11'
}
複製代碼
module的gradlebash
//多模塊項目,這個必須在使用到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"
}
複製代碼
- 修飾構造方法
- 修飾變量,在宿主類裏,引入要注入的實例
生產實例的工廠,每個實例都是經過@Provides修飾的方法提供的app
專門解決,不是本身寫的類沒法在其構造函數上加@Inject的狀況框架
固然本身寫的類也能夠經過@Provides修飾的方法提供,這樣就不會找@Inject的構造函數了ide
Component是橋樑紐帶,是一個接口函數
功能1:組織依賴關係(鏈條)gradle
一個Component能夠組織多個Module 一個Component還能夠組織引入其餘的Componentui
依賴的查找順序爲:先找@Module,若是找到了就中止,若是找不到就去找@Injectthis
功能2:爲宿主類提供Inject方法google
全部實例類型所有在我掌控之中 最簡單的狀況 (不須要Module)
(要注入的實例的類都是本身寫的,不須要Module,本身寫的類本身用@inject修飾構造方法)
class Apple @Inject constructor(){
var color:String ="red"
}
複製代碼
注意:參數必須爲要使用對象注入的類
@Component
interface FruitComponent {
fun inject(activity: MainActivity)
}
複製代碼
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)
}
}
複製代碼
有些實例類型,我沒法掌控
別慌!@Module來幫忙
兩種狀況
@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)
}
}
複製代碼
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所注入的類同樣,會報錯
}
複製代碼
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)
}
複製代碼
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:Scope, Component間依賴和subComponent