Dagger2最简单的入门

啰嗦几句

这几天看Dagger看得晕头转向的,我觉得还不如动手敲几行代码,跑一跑遛一遛,边敲边理解,一口吃不成胖子,先从最简单的开始。

既然Dagger的最主要功能就是依赖注入,我就来一个炒鸡简单的demo,在一个Activity中注入一个对象,然后显示这个对象的信息,就这样。一下子讲太多的东西反而会让你望而却步。

dependencies

1
2
3
4
dependencies {
annotationProcessor "com.google.dagger:dagger-compiler:2.16"
compile "com.google.dagger:dagger:2.16"
}

Click and drag to move

Student

用@Inject注解构造方法

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

public String name;

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

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

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

Click and drag to move

Component

创建一个Component类,用@Component注解,这是一个注入类,先依样画葫芦照着写就是了,inject方法的参数是我们要在里面注入对象的MainActivity

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

Click and drag to move

MainActivity

在MainActivity里写一个全局变量student,用@Inject注解,注意被注入的对象不能为private

然后在onCreate里调用DaggerMainActivityComponent.create().inject(this)就可以成功注入student了

接下来就可以使用这个对象了

如果报找不到DaggerMainActivityComponent可以先菜单Build->Make Project编译一下

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对象并没有实例化,却可以直接使用,这就是Dagger依赖注入的神奇之处

imgClick and drag to move

背后的原理

你可能会有疑问我们创建的是MainActivityComponent,那DaggerMainActivityComponent是哪来的呢?

是Dagger根据MainActivityComponent为我们创建,不仅如此,还在以下路径创建了以下类

我们分别看下生成的这三个类的代码

imgClick and drag to move

Student_Factory

一个Seudent的工厂类,代码很简单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Generated by Dagger (https://google.github.io/dagger).
package com.him.hisapp;

import dagger.internal.Factory;

public final class Student_Factory implements Factory<Student> {
private static final Student_Factory INSTANCE = new Student_Factory();

@Override
public Student get() {
return provideInstance();
}

public static Student provideInstance() {
return new Student();
}

public static Student_Factory create() {
return INSTANCE;
}

public static Student newStudent() {
return new Student();
}
}

Click and drag to move

MainActivity_MembersInjector

看名字就知道这是个注入器,Component就是调用这个注入器来把变量注入Activity的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Generated by Dagger (https://google.github.io/dagger).
package com.him.hisapp;

import dagger.MembersInjector;
import javax.inject.Provider;

public final class MainActivity_MembersInjector implements MembersInjector<MainActivity> {
private final Provider<Student> studentProvider;

public MainActivity_MembersInjector(Provider<Student> studentProvider) {
this.studentProvider = studentProvider;
}

public static MembersInjector<MainActivity> create(Provider<Student> studentProvider) {
return new MainActivity_MembersInjector(studentProvider);
}

@Override
public void injectMembers(MainActivity instance) {
injectStudent(instance, studentProvider.get());
}

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

Click and drag to move

DaggerMainActivityComponent

代码也很简单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// Generated by Dagger (https://google.github.io/dagger).
package com.him.hisapp;

import com.google.errorprone.annotations.CanIgnoreReturnValue;

public final class DaggerMainActivityComponent implements MainActivityComponent {
private DaggerMainActivityComponent(Builder builder) {}

public static Builder builder() {
return new Builder();
}

public static MainActivityComponent create() {
return new Builder().build();
}

@Override
public void inject(MainActivity activity) {
injectMainActivity(activity);
}

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

public static final class Builder {
private Builder() {}

public MainActivityComponent build() {
return new DaggerMainActivityComponent(this);
}
}
}

Click and drag to move

我们从MainActivity里DaggerMainActivityComponent.create().inject(this)的调用开始一层层进入就可以知道整个的注入流程

1
2
// MainActivity的onCreate()中调用
DaggerMainActivityComponent.create().inject(this);

Click and drag to move

DaggerMainActivityComponent的inject()方法里再调用injectMainActivity(),在这里就创建了Student对象,然后和activity对象一起传入MainActivity_MembersInjector.injectStudent()方法

1
2
3
4
5
6
7
8
9
10
@Override
public void inject(MainActivity activity) {
injectMainActivity(activity);
}

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

Click and drag to move

在MainActivity_MembersInjector的injectStudent方法里可看到,把student实例对象赋给了MainActivity的student成员变量

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

Click and drag to move

看完整个流程是不是就明白了注入的过程

Dagger帮我们生成代码,做了很多工作,我们只需要简单写一些注解就可以完成对象的依赖注入。