首页 > 代码库 > dagger2系列之生成类实例(自己)

dagger2系列之生成类实例(自己)

  上一节的最后,我讲到一次注入生成类实例的生成步骤。先来回顾一下:

    1  Module中存在创建方法,则看此创建方法有没有参数

      如果有参数,这些参数也是由Component提供的,返回步骤1逐一生成参数类实例,最后再生成最终类实例--ok

      如果无参数,则直接由这个方法生成最终类实例

   2    Module中没有创建方法,则从构造函数里面找那个用@Inject注解的构造函数

      如果该构造函数有参数,则也是返回到步骤1逐一生成参数类实例,最后调用该构造函数生成类实例

      如果该构造函数无参数,则直接调用该构造函数生成类实例

  本节就是验证这些步骤是否可行!!!无参数在上一节中已经介绍过了,所以此处验证都是带参数的

 

<一>Module中存在创建方法,有参数

    按照上面的步骤,它会先看Component提供的Module有没有提供这个参数,没有的话找这个参数实体类的构造函数生成实例(@inject)。

    1  被依赖类和参数的实体类都是由Module创建

NeedProvide3实例

public class NeedProvide3 {

    public NeedProvide3(Bean3 bean){
    }

    public void printMethod(){
        Log.d("Dagger.class","NeedProvide3----printMethod()");
    }

}

  注意这里的构造器没有用@inject注解修饰,因为这个类的实例要由Module提供。

参数Bean3

public class Bean3 {
    public Bean3(){
        Log.d("Dagger.class","-------bean3");
    }
}

  注意这里的构造器没有用@inject注解修饰,因为这个类的实例要由Module提供。

提供NeedProvide3实例

@Module
public class ProvideModule31 {

    @Provides
   public NeedProvide3 provideNeedProvide(Bean3 bean){
        return  new NeedProvide3(bean);
   }

}

提供参数Bean3

@Module
public class ProvideModule32 {

    @Provides
    public Bean3 provideBean(){
        return new Bean3();
    }

}

桥梁Component

@Component(modules={ProvideModule31.class, ProvideModule32.class})
public interface NeedComponent3 {
    void inject(TargetActivity3 activity);
    Bean3 getBean();//方法名字随意
}

  这里需要提供一个方法,当寻找参数的时候会用到,不写会报错!!!

目标类

public class TargetActivity3 extends AppCompatActivity {

    @Inject
    NeedProvide3 mNeedProvide3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DaggerNeedComponent3.builder().build().inject(this);
        Log.d("Dagger.class","qian----");
        mNeedProvide3.printMethod();
        Log.d("Dagger.class","--------hou");

    }
}

  运行看下打印结果:技术分享

  

  2  被依赖类的参数由Module提供,参数由@inject方式创建

这里只有两个类需要改动,这里只贴出这两个类的代码:

参数类:用@inject注解修饰

public class Bean3 {
    @Inject
    public Bean3(){
        Log.d("Dagger.class","-------bean3");
    }
}

桥梁Component:删掉了提供Bean3的Module,让Bean3实例由@inject注解创建

@Component(modules={ProvideModule31.class})
public interface NeedComponent3 {
    void inject(TargetActivity3 activity);
}

  运行的打印结果和上面的是一样的,说明这两种方法都可以的!!!

 

<二>Module中不创建方法,有参数

  1  Module中提供参数,被依赖类通过构造器的@inject方式创建

被依赖类:通过@inject方式创建实例

public class NeedProvide4 {
    @Inject
    public NeedProvide4(Bean4 bean){
    }

    public void printMethod(){
        Log.d("Dagger.class","NeedProvide4----printMethod()");
    }
}

参数Bean4:无@inject注解

public class Bean4 {
    public Bean4(){
        Log.d("Dagger.class","-------bean");
    }
}

提供参数:

@Module
public class ProvideModule4 {

    @Provides
    public Bean4 provideBean(){
        return new Bean4();
    }

}

桥梁Component

@Component(modules = ProvideModule4.class)
public interface NeedComponent4 {
    void inject(TargetActivity4 activity);
}

  运行打印的结果为:技术分享

 

2  被依赖类和参数的实体类都由@inject方式创建

桥梁Component

@Component
public interface NeedComponent4 {
    void inject(TargetActivity4 activity);
}

  被依赖类和参数都需要在构造器上使用@inject注解修饰。此处就不贴代码了,运行之后的打印结果和上面的一样。

 

  本篇主要验证开头所讲的步骤中涉及到的那几种方法是否行的通。最后总结如下:

    1  参数和被依赖类的实例化有两种方法,Module和@inject方式。

    2  当创建依赖类需要参数的时候,参数的实例化有两种方法

        1>Module提供:

          如果依赖类和参数都是Module提供(不由同一个Module提供),那么需要在Component中声明一个方法显示提供,方法名字任意。

        2>@inject方式:

 

dagger2系列之生成类实例(自己)