dagger2的GitHub地址
优秀的小白入门博客
大神的dagger2详解博客
本文Demo
activity(Inject成员变量,告诉dagger拿到对象之后赋值给它)
@Inject
lateinit var person: Person
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
DaggerMainComponent.builder().build().injectMain(this)
}
Component
@Component
interface MainComponent{
fun injectMain(activity: MainActivity)
}
需要inject拿到的对象(告诉dagger我要拿到这个类的对象)
class Person @Inject constructor() {
}
@Inject有两项职责:
创建好这三个类要先build一下,然后会自动生成对应的Component类。
先看看生成的DaggerMainComponent类源码
public final class DaggerMainComponent implements MainComponent {
private DaggerMainComponent(Builder builder) {}
public static Builder builder() {
return new Builder();
}
public static MainComponent create() {
return new Builder().build();
}
@Override
public void injectMain(MainActivity activity) {
injectMainActivity(activity);
}
private MainActivity injectMainActivity(MainActivity instance) {
MainActivity_MembersInjector.injectPerson(instance, new Person());
return instance;
}
public static final class Builder {
private Builder() {}
public MainComponent build() {
return new DaggerMainComponent(this);
}
}
}
可以看到DaggerMainComponent.builder().build()和DaggerMainComponent.create()效果是一样的。
编译之后生成了对应的Injector类
person对象是在injectMainActivity方法中new出来的。
MainActivity_MembersInjector.injectPerson(instance, new Person());
再看看Injector的源码
public final class MainActivity_MembersInjector implements MembersInjector {
private final Provider personProvider;
public MainActivity_MembersInjector(Provider personProvider) {
this.personProvider = personProvider;
}
public static MembersInjector create(Provider personProvider) {
return new MainActivity_MembersInjector(personProvider);
}
@Override
public void injectMembers(MainActivity instance) {
injectPerson(instance, personProvider.get());
}
public static void injectPerson(MainActivity instance, Person person) {
instance.person = person;
}
}
然后直接赋值到activity类的成员变量中
public static void injectPerson(MainActivity instance, Person person) {
instance.person = person;
}
有时候只用Inject不能获取到对象了,比如person是一个第三方库类,这样你就不能直接Inject它的构造方法了,这个时候就需要module和provide
activity
class MainActivity : AppCompatActivity() {
@Inject
lateinit var person: Person
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
DaggerMainComponent.builder().module(Module()).build().injectMain(this)
Log.d("eee=person", "" + person.hashCode())
}
}
Component(Module可以多个,逗号隔开)
@Component(modules = [Module::class])
interface MainComponent{
fun injectMain(activity: MainActivity)
}
Module
@Module
class Module {
@Provides
fun providePerson():Person{
return Person()
}
}
person
class Person {}
可以看到这个示例代码中其实就是在module中创建好了对象,最后传到activity中的。
DaggerMainComponent中的关键代码是injectMain
@Override
public void injectMain(MainActivity activity) {
injectMainActivity(activity);
}
private MainActivity injectMainActivity(MainActivity instance) {
MainActivity_MembersInjector.injectPerson(
instance, Module_ProvidePersonFactory.proxyProvidePerson(module));
return instance;
}
调用Module_ProvidePersonFactory的proxyProvidePerson,就是拿module中你创建的那个对象
public static Person proxyProvidePerson(Module instance) {
return Preconditions.checkNotNull(
instance.providePerson(), "Cannot return null from a non-@Nullable @Provides method");
}
MainActivity_MembersInjector.injectPerson就是最后的赋值操作了
public static void injectPerson(MainActivity instance, Person person) {
instance.person = person;
}
当person有多个构造函数并Inject了多个构造的时候,provide不知道要提供哪个构造方法,将造成“依赖迷失”
activity
class MainActivity : AppCompatActivity() {
@Inject
lateinit var bananaSet:Set
@Inject
lateinit var setBananaBean: SetBananaBean
@Inject
lateinit var bananaByString:Map
@Inject
lateinit var bananaByClass:Map,BananaBean>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val build = DaggerMainComponent.builder().build()
build.injectMain(this)
val banana = build.setBanana()
Log.d("eee=banana1",banana.toString())
Log.d("eee=banana2",banana.toString())
Log.d("eee=banana3",banana.toString())
Log.d("eee=bananaSet",bananaSet.toString())
Log.d("eee=setBananaBean",setBananaBean.toString())
Log.d("eee=component string",build.bananaByString().toString())
Log.d("eee=component class",build.bananaByClass().toString())
Log.d("eee=Inject string",bananaByString.toString())
Log.d("eee=Inject class",bananaByClass.toString())
}
}
module
@Module
class DrinkModule {
@Provides
@IntoSet
fun providerBanana(): BananaBean {
return BananaBean("特朗普香蕉")
}
}
@Module
class FruitModule {
@Provides
@IntoSet
fun providerBanana(): BananaBean {
return BananaBean("特朗普--香蕉")
}
}
@Module
class MultiModule {
@Provides
@ElementsIntoSet
fun providerBananaSet(): Set {
var set = HashSet()
set.add(BananaBean("布什香蕉"))
set.add(BananaBean("约翰逊香蕉"))
return set
}
@Provides
@IntoMap
@StringKey("a")
fun providerBananaMap(): BananaBean {
return BananaBean("a apple")
}
@Provides
@IntoMap
@ClassKey(Person::class)
fun providerClassMap(): BananaBean {
return BananaBean("class apple")
}
}
bean(kotlin中不要像Java那样单独写个方法写构造,否则inject无效)
class SetBananaBean @Inject constructor(val set:Set) {
override fun toString(): String {
return super.toString()
}
}
class BananaBean(val s:String) {
override fun toString(): String {
return s
}
}
Component
@Component(modules = [Module::class,FruitModule::class,DrinkModule::class,MultiModule::class])
interface MainComponent{
fun injectMain(activity: MainActivity)
fun setBanana():Set
fun bananaByString():Map
fun bananaByClass():Map,BananaBean>
}
运行结果
D/eee=banana1: [特朗普香蕉, 约翰逊香蕉, 特朗普--香蕉, 布什香蕉]
D/eee=banana2: [特朗普香蕉, 约翰逊香蕉, 特朗普--香蕉, 布什香蕉]
D/eee=banana3: [特朗普香蕉, 约翰逊香蕉, 特朗普--香蕉, 布什香蕉]
D/eee=bananaSet: [布什香蕉, 约翰逊香蕉, 特朗普香蕉, 特朗普--香蕉]
D/eee=setBananaBean: com.example.admin.baladagger2.test1.SetBananaBean@676e725
D/eee=component string: {a=a apple}
D/eee=component class: {class com.example.admin.baladagger2.test1.Person=class apple}
D/eee=Inject string: {a=a apple}
D/eee=Inject class: {class com.example.admin.baladagger2.test1.Person=class apple}
查看源码知道关键代码在DaggerMainComponent类,继承MainComponent重写setBanana方法
@Override
public Set setBanana() {
return SetBuilder.newSetBuilder(3)
.add(FruitModule_ProviderBananaFactory.proxyProviderBanana(fruitModule))
.add(DrinkModule_ProviderBananaFactory.proxyProviderBanana(drinkModule))
.addAll(MultiModule_ProviderBananaSetFactory.proxyProviderBananaSet(multiModule))
.build();
}
public MainComponent build() {
if (fruitModule == null) {
this.fruitModule = new FruitModule();
}
if (drinkModule == null) {
this.drinkModule = new DrinkModule();
}
if (multiModule == null) {
this.multiModule = new MultiModule();
}
return new DaggerMainComponent(this);
}
@Override
public void injectMain(MainActivity activity) {
injectMainActivity(activity);
}
private MainActivity injectMainActivity(MainActivity instance) {
MainActivity_MembersInjector.injectBananaSet(instance, setBanana());
MainActivity_MembersInjector.injectSetBananaBean(instance, getSetBananaBean());
MainActivity_MembersInjector.injectBananaByString(instance, bananaByString());
MainActivity_MembersInjector.injectBananaByClass(instance, bananaByClass());
return instance;
}
例如:
A component中有 fun inject(Bala:Activity)
B component中也有 fun inject(Bala:Activity)
使用场景:你需要的对象中需要其他的对象,例如“车”需要有”颜色“
Car
class Car(val brand:String,val color:VehicleColor) {
fun go(){
Log.d("eee=car",brand+"go --color is"+color.color)
}
}
CarComponent
@Component(modules = CarModule.class, dependencies = ColorComponent.class)
public interface CarComponent {
void inject(CarActivity activity);
}
CarModule
@Module
public class CarModule {
@Provides
Car provideCar(VehicleColor color){
return new Car("兰博基尼",color);
}
}
ColorComponent
@Component(modules = ColorModule.class)
public interface ColorComponent {
VehicleColor carColor();
}
ColorModule
@Module
public class ColorModule {
@Provides
VehicleColor provideCarColor(){
return new VehicleColor("红色");
}
}
Component2
@Component(modules = [Module2::class],dependencies = [MainComponent::class])
interface Component2 {
fun inject(activity:Test2)
}
Module2
@Module
class Module2 {
@Provides
fun provideTest2():Person2{
return Person2()
}
}
VehicleColor
class VehicleColor(val color:String)
CarActivity
class CarActivity: AppCompatActivity() {
@Inject
lateinit var car: Car
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
DaggerCarComponent.builder().colorComponent(DaggerColorComponent.create()).build().inject(this)
car.go()
}
}
运行结果
D/eee=car: 兰博基尼go --color is红色
分析
首先直接看inject这个方法做了啥?在DaggerCarComponent中可以看到
@Override
public void inject(CarActivity activity) {
injectCarActivity(activity);
}
private CarActivity injectCarActivity(CarActivity instance) {
CarActivity_MembersInjector.injectCar(instance, getCar());
return instance;
}
private Car getCar() {
return CarModule_ProvideCarFactory.proxyProvideCar(
carModule,
Preconditions.checkNotNull(
colorComponent.carColor(), "Cannot return null from a non-@Nullable component method"));
}
getCar方法中拿到的就是car的对象,里面传入carModule和colorComponent,module中有car的对象的方法,component中有car所需要的颜色。然后在CarModule_ProvideCarFactory中创建中car对象
public static Car proxyProvideCar(CarModule instance, VehicleColor color) {
return Preconditions.checkNotNull(
instance.provideCar(color), "Cannot return null from a non-@Nullable @Provides method");
}
car就是这样创建和传递的。现在的问题是carModule和colorComponent是怎么出来的。在DaggerCarComponent的Builder类中可以看到
public static final class Builder {
private CarModule carModule;
private ColorComponent colorComponent;
private Builder() {}
public CarComponent build() {
if (carModule == null) {
this.carModule = new CarModule();
}
if (colorComponent == null) {
throw new IllegalStateException(ColorComponent.class.getCanonicalName() + " must be set");
}
return new DaggerCarComponent(this);
}
public Builder carModule(CarModule carModule) {
this.carModule = Preconditions.checkNotNull(carModule);
return this;
}
public Builder colorComponent(ColorComponent colorComponent) {
this.colorComponent = Preconditions.checkNotNull(colorComponent);
return this;
}
}
虽然CarModule没有直接操作,但是build方法中判断为空的时候会自动new出来,然后赋值给DaggerCarComponent的成员变量carModule。colorComponent是你自己传进去的(通过DaggerColorComponent.create())
public final class DaggerColorComponent implements ColorComponent {
private ColorModule colorModule;
private DaggerColorComponent(Builder builder) {
initialize(builder);
}
public static Builder builder() {
return new Builder();
}
public static ColorComponent create() {
return new Builder().build();
}
@SuppressWarnings("unchecked")
private void initialize(final Builder builder) {
this.colorModule = builder.colorModule;
}
@Override
public VehicleColor carColor() {
return ColorModule_ProvideCarColorFactory.proxyProvideCarColor(colorModule);
}
public static final class Builder {
private ColorModule colorModule;
private Builder() {}
public ColorComponent build() {
if (colorModule == null) {
this.colorModule = new ColorModule();
}
return new DaggerColorComponent(this);
}
public Builder colorModule(ColorModule colorModule) {
this.colorModule = Preconditions.checkNotNull(colorModule);
return this;
}
}
}
关键代码来了,在build方法中可以看到,里面new了一个ColorModule出来,ColorModule中就提供了获取VehicleColor也就是颜色对象的方法。然后把ColorModule对象赋值给Builder类的成员变量,再new一个DaggerColorComponent(this),这个this就是保存了ColorModule对象的Builder。然后在DaggerColorComponent里面又把Builder中colorModule拿出来保存在自己的成员变量中,此时DaggerColorComponent也就拿到了颜色。
最后还是一样的套路,拿到了car构造所需要的参数(在DaggerColorComponent中),拿到了可以创建car的方法(在carModule中),然后再用inject赋值
Bike
class Bike(val color: String) {
fun go(){
Log.d("eee=bike","bike is running -- color is "+color)
}
}
BikeComponent
@Subcomponent(modules = BikeModule.class)
public interface BikeComponent {
Bike supplyBike();
@Subcomponent.Builder
interface Builder{
Builder bikeModule(BikeModule module);
BikeComponent build();
}
}
BikeModule
@Module
public class BikeModule {
@Provides
Bike provideCar(){
return new Bike(" black ");
}
}
Brand
class Brand(val name:String) {
override fun toString(): String {
return "Brand{ $name }"
}
}
BrandComponent
@Component(modules =[ BrandModule::class])
interface BrandComponent {
fun inject(activity: BikeActivity)
fun supplyBikeComponentBuild():BikeComponent.Builder
}
BrandModule
@Module(subcomponents = [BikeComponent::class])
class BrandModule {
@Provides
fun provideBrand(): Brand {
return Brand("林肯加长版")
}
}
BikeActivity
class BikeActivity: AppCompatActivity() {
@Inject
lateinit var brand: Brand
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val brandComponent = DaggerBrandComponent.builder().build()
brandComponent.inject(this)
val supplyBike = brandComponent.supplyBikeComponentBuild().build().supplyBike()
supplyBike.go()
Log.d("eee=brand",brand.toString())
}
}
运行结果
D/eee=bike: bike is running -- color is black
D/eee=brand: Brand{ 林肯加长版 }
源码都是类似的,没有分析的意义
https://www.jianshu.com/p/5fd066bf28fa