Dagger2基本整体使用讲解--第二章

首先看一张图



第一看这个图我也懵逼了,这是啥呀,这相当Dagger2的整体吧

举个例子,比如说我通过@Inject去创建一个对象,而这个对象的不是我们能编写的(例如系统的,jar包提供的),我们就不能用@Inject方式来创建这个对象

例如

@Inject
public TextView textView;

TextView是android库中的,我们没办法用@Inject去注解构造方法,这下改怎么办呢?

上面图就是解决这个的办法

下面解释下:

1:Compenent第一章节的时候说过,连接器,他是连接Module和Container的桥梁,我第一章节就说了只有在调用了连接器的的方法,这个对象才开始创建

2:Module 提供创建对象的方法

3:Container需要创建对象的,例子中就Activity

解决上面的问题

1:创建Module(供给类,告诉创建TextView,怎么创建)

//提供对象的Module
@Module
public class TestModule {

    //为啥需要这个呢,因为provideTextView需要Context做行参,我们当然也要提供一个获取Context的方法啊
    @Provides
    public Context provideContext(){
        //这是一个全局的Application
        Log.d("wyz","执行了:provideContext()");
        return App.application;
    }

    //必须使用 @Provides 告诉Compenent 这是一个供给方法 这里我要提供一个TextView
    @Provides
    public TextView provideTextView(Context context){
        // 这里需要一个上下文,我先写null,后期提供方案
        TextView textVie=new TextView(context);
        Log.d("wyz","执行了:provideTextView()创建TextView:"+textVie.hashCode());

        return textVie;
    }
}


2:创建连接器

//告诉Component的modules,可以看出是一个数组,所以可以提取多个
//    重要的事情说三遍 接口 接口 接口
@Component(modules = {TestModule.class})
public interface TestCompenent {
    void inject(MainActivity mainActivity);//提供链接方法
}

3:最好Build下,生成那个连接器的类,编写MainActivity

public class MainActivity extends AppCompatActivity {

    @Inject
    public TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DaggerTestCompenent.create().inject(this);
        textView.setText("Dagger2");
        log("大吉大利,我没崩溃textView:"+textView.hashCode());
    }

    public void log(String value){
        Log.d("wyz", value);
    }
}

运行结果

04-18 18:13:24.247 31407-31407/com.example.wenyingzhi.myapplication D/wyz: 执行了:provideContext()
04-18 18:13:24.252 31407-31407/com.example.wenyingzhi.myapplication D/wyz: 执行了:provideTextView()创建TextView:213786299
04-18 18:13:24.252 31407-31407/com.example.wenyingzhi.myapplication D/wyz: 大吉大利,我没崩溃textView:213786299

注意到了吗?2个TextView的HashCode是一样哦,所以是一个对象

分析下过程

1:当我们调用DaggerTestCompenent.create().inject(this);连接器的方法后

2:会看当前类需要@Inject注解的对象,寻找构造方法,有没有通过@Inject注解,发现没有

3:去Compenent关联的Modules中找@Provides注解的方法,并且是返回TextView的方法,看方法参数需要Context

4:再去Compenent关联的Modules中找@Provides注解的方法,并且是返回Context的方法

然后按个调用,就完成了一个对象的初始化操作,总之就是你要初始化对象关联的对象,参数都必须能找到,2种方式Module中找到或者类的本身使用了@Inject

下面来个整体的demo

描述:一个Teacher类,类的构造方法,传入一个Student学生类和StudentClass学生科目类

public class Teacher {
    public Student student;
    public StudentClass studentClass;

    @Inject
    public Teacher(Student student, StudentClass studentClass) {
        this.student = student;
        this.studentClass = studentClass;
    }
}
@Module
public class TeacherModule {
    @Provides
    public Student provideStudent(){
        return new Student();
    }

    @Provides
    public StudentClass provideStudentClass(){
        return new StudentClass();
    }
}
@Component(modules = {TeacherModule.class})
public interface TeacherCompenent {
    void inject(MainActivity mainActivity);
}

因为Teacher的构造方法我通过了@Inject注解所以,不需要再Module处定义@Provide,同理如果我的Student或StudentClass类的构造方法也@Inject注解了,Module中也不需要提供@Provide

例如这样

public class Student {
    @Inject
    public Student() {
    }
}

那么Module中就不再需要定义 provideStudent()方法

@Module
public class TeacherModule {

    @Provides
    public StudentClass provideStudentClass(){
        return new StudentClass();
    }
}

猜你喜欢

转载自blog.csdn.net/wenyingzhi/article/details/79994155