上一篇主要讲解了一下MVP框架的搭建和组成,这篇主要来讲在MVP上添加Dagger2依赖注入。
在之前的MVP中,我们都是在V中直接new一个P的,现在我们需要将new的操作放在Dagger2中,让它帮我们完成。
提到Dagger2的注入,我们就知道我们至少需要两个类Component和Module(可以不使用Module,但为了通用性和易懂性,建议使用Module),所以需要新建这两个类。Dagger2的注入,是一个类一个注入器,这样我们就可以根据模块的不同来新建不同模块下的注入器了。
首先在oneActivity中新建一个包名叫daggerComponent,然后在该包下新建Module和Component。这里要解释一下为什么我会将这两个类放在一个包中,官方的做法是这两个类是和MVP类同级的,也就是说并没有daggerComponent这个包,而我增加这个包,主要是为了防止这个模块里面需要多个注入器,也是为了方便和简洁美观。
在Module中我们主要提供P的实例化构成,如下:
@Module
public class MainModule {
private final IMainConstane.IMainView mView;
public MainModule(IMainConstane.IMainView mView) {
this.mView = mView;
}
@Provides
IMainConstane.IMainView providesMainView() {
return mView;
}
@Provides
IMainConstane.IMainPresenter providesMainPresenter(IMainConstane.IMainView view, IUserModel usermodel) {
return new MainPresenter(view, usermodel);
}
}
注意这里的变量类型都是接口,要习惯接口化编程。然后看一下Component的代码:
@SingleUserModel
@Component(dependencies = UserModelComponent.class, modules = MainModule.class)
public interface MainComponent {
void inject(MainActivity activity);
}
@SingleUserModel标签是我自定义的,主要是因为我的UserModelComponent中使用了@Singleton标签,而dagger2中不允许两个依赖的Component有一样的@Scop。然后是dependencies依赖,我们在构建P的时候,是需要数据模块对象的,所以这里依赖UserModelComponent让它提供数据模块对象。MainModule类我们刚看了,没有什么,只是一个很普通的Module,然后我们来看一下UserModel的注入器UserModelComponent,可以看到里面就一句话:
@Singleton
@Component(modules = {UserModule.class, ApplicationModule.class})
public interface UserModelComponent {
IUserModel getUserModel();
}
这个接口是给依赖它的类提供数据对象的,比如上面的MainComponent依赖这个UserModelComponent,那么这个接口就是当作一个参数传递给MainComponent。
一个Component通常是承载一个Module,我们看一下UserModeul:
@Module
public class UserModule {
@Provides
@Singleton
public IUserModel providesUserModule(Context context) {
return new UserModelImpl(context);
}
}
看到这个providesUserModule方法是被打上@Singleton单例标签的,但它真的可以实现单例吗?后面再说!该方法还需要一个Context参数(这个参数其实在数据模块中没被用到,只不过是我加上的,这样容易理解后面的内容),它从哪里来?我们回到UserModelComponent中,看到它还承载了一个Module类,那就是ApplicatinModule,看这个类:
@Module
public final class ApplicationModule {
private final Context mContext;
ApplicationModule(Context context) {
mContext = context;
}
@Provides
Context provideContext() {
return mContext;
}
}
注意这个类在项目中的位置,它是和MyApplication同级的,也就是说它提供全局的实例,比如全局上下文,比如全局的环境实例。
最后MainComponent通过编译之后生成DaggerMainComponent,执行inject方法进行依赖注入,最后在MainActivity中实例化了mMainPresenter变量,我们也就可以使用它了。
详细的Dagger2+MVP融合,一行一行分析,一点一点进步,之一