Dagger2,一个依赖注入框架,在编译时处理注解,自动生成.java文件,Mvp架构中使用Dagger2,不需要手动创建Presenter,通过注解注入宿主Activity。
LoginComponent接口,用@Component和@ActivityScope注解,提供注入方法和注入目的类。
@ActivityScope
@Component(modules = LoginModule.class)
public interface LoginComponent {
void inject(LoginActivity activity);
}
LoginModule类,@Module注解,provider方法,用@Provides和@ActivityScope注解,提供注入对象构造参数。
@Module
public class LoginModule {
private ILoginView iView;
public LoginModule(ILoginView iView) {
this.iView = iView;
}
@Provides
@ActivityScope
public ILoginView provideILoginView() {
return this.iView;
}
}
LoginPresenter,注入对象,构造方法@Inject注解。
@Inject
public LoginPresenter(ILoginView iView, long id, String userName) {
this.iLoginView = iView;
this.id = id;
this.userName = userName;
}
在Activity内部,定义LoginPresenter,@Inject注解。
@Inject
LoginPresenter mLoginPresenter;
DaggerLoginComponent.builder().loginModule(new LoginModule(this)).build().inject(this);
Activity不需要主动创建LoginPresenter对象,调用inject注入方法,直接使用。
DaggerLoginComponent是一个自动生成的java类,实现LoginComponent接口,该接口自定义。
DaggerLoginComponent包含Provider引用,注入对象构造参数的Provider提供者。
private Provider provideILoginViewProvider;
private Provider getIdProvider;
private Provider getUserNameProvider;
DaggerLoginComponent内部类Builder,封装Module,loginModule方法,设置LoginModule对象,LoginModule类是注入对象构造参数具体提供者。
build方法,创建DaggerLoginComponent对象,构造方法入参Builder对象。
private DaggerLoginComponent(Builder builder) {
initialize(builder);
}
根据Builder的LoginModule类,初始化DaggerLoginComponent内部的Provider,即参数工厂,每一个构造参数,都生成一个构造工厂类。
private void initialize(final Builder builder) {
this.provideILoginViewProvider =
DoubleCheck.provider(LoginModule_ProvideILoginViewFactory.create(builder.loginModule));
this.getIdProvider = DoubleCheck.provider(LoginModule_GetIdFactory.create(builder.loginModule));
this.getUserNameProvider =
DoubleCheck.provider(LoginModule_GetUserNameFactory.create(builder.loginModule));
}
LoginModule_ProvideILoginViewFactory类,实现Factory,Factory继承Provider,根据Builder对象内部配置的LoginModel,工厂提供静态create方法创建工厂对象,工厂封装LoginModule。
每个工厂实现Provider接口get方法,具体由内部LoginModule类提供参数。
inject方法,传入被注入的对象LoginActivity。
@Override
public void inject(LoginActivity activity) {
injectLoginActivity(activity);
}
调用内部injectLoginActivity方法。
private LoginActivity injectLoginActivity(LoginActivity instance) {
LoginActivity_MembersInjector.injectMLoginPresenter(instance, getLoginPresenter());
return instance;
}
injectMLoginPresenter方法,将LoginPresenter对象其赋值给LoginActivity实例对象内部变量。
getLoginPresenter方法,返回LoginPresenter注入对象,构造方法@Inject注解。
private LoginPresenter getLoginPresenter() {
return new LoginPresenter(
provideILoginViewProvider.get(), getIdProvider.get(), getUserNameProvider.get());
}
LoginPresenter构造方法参数,参数工厂Provider提供,get方法,调用内部LoginModule的@Provides注解方法。
Dagger2的本质是通过Apt技术自动生成对象并赋值注入。
Dagger2解耦Activity和Presenter,当改动LoginPresenter的构造方法时,不需要改动Activity。比如我在LoginPresenter的构造方法增加一个参数userName,这时,只需要在LoginModule类中,添加一个@Provides注解的方法,该方法返回一个String类型userName即可。
任重而道远