Dagger2依赖注入
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标注
@Inject
public LoginPresenter(ILoginView iView) {
this.iLoginView = iView;
}
注入对象的构造方法,用@Inject注解。在Activity内部,定义LoginPresenter用@Inject注解。
@Inject
LoginPresenter mLoginPresenter;
DaggerLoginComponent.builder().loginModule(new LoginModule(this)).build().inject(this);
在Activity内部,不需要主动new创建LoginPresenter对象,可以直接使用,调用上面的方法inject注入。
DaggerLoginComponent是一个自动生成的java类,实现LoginComponent接口,该接口是我们自己定义的,代表注入内容的对象,@Component注解,注解的modules是LoginModule。
创建一个Builder对象,DaggerLoginComponent内部类Builder,loginModule方法,设置创建的LoginModule对象,LoginModule中配置了注入者LoginPresenter创建时需要的参数。
然后,build方法,创建一个DaggerLoginComponent对象,构造方法,传入Builder,DaggerLoginComponent内部包含一个Provider<ILoginView>,如果有构造方法有其他参数,也会生成其他的Provider。
private DaggerLoginComponent(Builder builder) {
initialize(builder);
}
在build方法创建时,initialize方法,初始化Provider<ILoginView>。
private void initialize(final Builder builder) {
this.provideILoginViewProvider =
DoubleCheck.provider(LoginModule_ProvideILoginViewFactory.create(builder.loginModule));
}
LoginModule_ProvideILoginViewFactory是自动生成的类,根据Builder对象内部配置的LoginModel,create方法,创建一个ILoginView工厂提供者,该工厂封装LoginModel。
最后一步,inject方法,传入组件LoginActivity。
@Override
public void inject(LoginActivity activity) {
injectLoginActivity(activity);
}
调用内部injectLoginActivity方法。
private LoginActivity injectLoginActivity(LoginActivity instance) {
LoginActivity_MembersInjector.injectMLoginPresenter(instance, getLoginPresenter());
return instance;
}
getLoginPresenter方法,返回一个LoginPresenter注入对象,生成对象的构造方法被@Inject注解。LoginPresenter构造方法参数,由内部Provider提供,多个参数将会有多个Provider。
private LoginPresenter getLoginPresenter() {
return new LoginPresenter(provideILoginViewProvider.get());
}
LoginModule_ProvideILoginViewFactory的get方法,将调用内部LoginModule的
@Provides注解方法,即provideILoginView,返回ILoginView,注入对象构造方法入参。
injectMLoginPresenter方法,将生成的LoginPresenter对象其赋值给LoginActivity内部定义的变量。
这样,上面那段代码就结束了,它的本质是生成一个注入对象并注入。
Dagger2解耦Activity和Presenter,当改动LoginPresenter的构造方法时,不需要改动Activity。比如我在LoginPresenter的构造方法增加一个参数userName,这时,只需要在LoginModule类中,添加一个@Provides注解的方法,该方法返回一个String类型userName即可。
任重而道远