Dagger除了可以在属性上表示@Inject注入对象外,还可以在方法上标识,如下所示

然后调用DaggerMainActivityComponent.create().inject(this)就可以注入对象了

public class MainActivity extends AppCompatActivity {

    // 这里不用标识
    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());
    }

    // 在方法上标识
    @Inject
    void setStudent(Student student) {
        this.student = student;
    }
}

Dagger帮我们生成了很多代码,我们可以看下注入的流程:

DaggerMainActivityComponent中inject()方法内部再调用injectMainActivity()方法

injectMainActivity()方法内部调用了MainActivity_MembersInjector.injectSetStudent()

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

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

我们再看下MainActivity_MembersInjector.injectSetStudent()方法内部,直接调用Activity中定义的setStudent方法注入student对象

public static void injectSetStudent(MainActivity instance, Student student) {
  instance.setStudent(student);
}

我们可以对比下以上injectSetStudent()方法和用@Inject标识成员变量时生成的injectSetStudent()的区别

一个是直接赋值,一个是调用set方法赋值,基本上大同小异

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