android Dagger2 多层注入

简单来说我们要实现的就是在MainActivity中注入一个Student对象,在Student对象中又注入一个Teacher对象

实现代码

二话不说,直接上代码

Student

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Student {

public String name;
@Inject
public Teacher teacher;

@Inject
public Student() {
this.name = "野猿新一";
}

public Student(String name) {
this.name = name;
}

@Override
public String toString() {
return String.format("我的名字叫%s啦,我们老师的名字叫%s", name, teacher.name);
}
}

Click and drag to move

Teacher

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Teacher {

public String name;

@Inject
public Teacher() {
this.name = "苍老湿";
}

public Teacher(String name) {
this.name = name;
}

@Override
public String toString() {
return String.format("我的名字叫%s啦", name);
}
}

Click and drag to move

MainActivityComponent

1
2
3
4
@Component
public interface MainActivityComponent {
void inject(MainActivity activity);
}

Click and drag to move

MainActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class MainActivity extends AppCompatActivity {

@Inject
Student student;

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

DaggerMainActivityComponent.create().inject(this);
TextView textView = findViewById(R.id.text);
textView.setText(student.toString());
}
}

Click and drag to move

运行结果

可以看到Student对象成功注入到了Activity中,而Student对象也成功注入到Student中

imgClick and drag to move

背后的原理

Dagger通过我们的注解自动生成了很多的代码,如下这些类都是Dagger帮我们生成的

里面的代码其实很简单,我就不一一黏贴上来了,自己可以建个工程跑一下就会生成这些文件,自己点进入看一下

imgClick and drag to move

我们主要看下注入的流程,从MainActivity中的注入开始看:

MainActivity的onCreate方法中开启注入

1
DaggerMainActivityComponent.create().inject(this);

Click and drag to move

DaggerMainActivityComponent中的代码,直接看很清晰

injectMainActivity完成的动作是把Student对象注入到MainActivity,通过MainActivity_MembersInjector.injectStudent()方法来完成

injectStudent完成的动作是把Teacher对象注入到Student中,通过Student_MembersInjector.injectTeacher()方法来完成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Override
public void inject(MainActivity activity) {
injectMainActivity(activity);
}

@CanIgnoreReturnValue
private MainActivity injectMainActivity(MainActivity instance) {
MainActivity_MembersInjector.injectStudent(instance, getStudent());
return instance;
}

private Student getStudent() {
return injectStudent(Student_Factory.newStudent());
}

@CanIgnoreReturnValue
private Student injectStudent(Student instance) {
Student_MembersInjector.injectTeacher(instance, new Teacher());
return instance;
}

Click and drag to move

最后看下以下两个Injector的注入实现,很简单,直接把注入对象赋值给被注入对象内的成员变量,大功告成

MainActivity_MembersInjector.injectStudent()方法:

1
2
3
public static void injectStudent(MainActivity instance, Student student) {
instance.student = student;
}

Click and drag to move

Student_MembersInjector.injectTeacher()方法:

1
2
3
public static void injectTeacher(Student instance, Teacher teacher) {
instance.teacher = teacher;
}

Click and drag to move