架构图:
现在有个需求,就是在mvp中使用dagger2,需要将p注入到v中。
首先我们需要创建一个p层类MainPresenter
public class MainPresenter {
@Inject
public MainPresenter() {
}
public void loadMain(){
Log.i("TAG","MainPresenter--->loadMain");
}
}
这个就是p层类的代码,@Inject 注解代表的意思是注入实例的时候,需要提供的构造方法。
在看下activity里的代码:
public class MainActivity extends DaggerAppCompatActivity{
@Inject
MainPresenter mainPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mainPresenter.loadMain();
}
}
这个代码最重要的就是首先我们继承了 DaggerAppCompatActivity,然后注入了MainPresenter实例。
MainActivity是怎样拿到MainPresenter实例的呢?
我们现在从下往上看:
MainActivty就相当于造车厂,他需要MainPresenter这个发动机零件,首先我们需要一个中间商。创建一个应用级别的中间商角色,如下:
/**
* AndroidInjectionModule:这个类不是我们写的,它是 Dagger 2.10 中的一个内部类,通过给定的 Module 为我们提供了 Activity 和 Fragment。
*
* AppModule:我们在这里提供了 retrofit、okhttp、持久化数据库、SharedPrefs。
*
* ActivityBuilder:我们自己创建的 Module,这个 Module 是给 Dagger 用的,我们将所有的 Activity 映射都放在了这里。
* Dagger 在编译期间能获取到所有的 Activity,我们的 App 中有 MainActivity 和 DetailActivity 两个 Activity,
* 因此我将这两个 Activity 都放在这里。
*/
@Singleton
@Component(modules = {
AndroidSupportInjectionModule.class,
AppModule.class,
ActivityBuilder.class})
public interface AppComponent extends AndroidInjector {
@Override
void inject(DaggerApplication instance);
@Component.Builder
interface Builder {
@BindsInstance
Builder application(Application application);
AppComponent build();
}
}
优化后写法:
@Singleton
@Component(modules = {
AndroidSupportInjectionModule.class,
AppModule.class,
ActivityBuilder.class})
public interface AppComponent extends AndroidInjector {
@Component.Builder
abstract class Builder extends AndroidInjector.Builder {}
}
这个中间商我们可以看到,他可以联系到三个零件公司,AppModule将支持造车厂所有零配件。AndroidSupportInjectionModule是一个注入activity时必须的,也就可以看成为造车厂提供所有的法律支持。最后就是我们要用到的ActivityBuidler,这个类其实是Activity和Moudle的联系桥梁
/**
* Created by mertsimsek on 25/05/2017.
* 通过这个类,我们开发方便的发现各个Activity对应着自己的NModule
*/
@Module
public interface ActivityBuilder {
@ContributesAndroidInjector(modules = MainActivityModule.class)
MainActivity bindMainActivity();
}
然后我们进入到Module中,这里是提供activity所需的所有@Inject 提供实例,初始化的地方,如下:
/**
* 这个module非常简单的发现,他是为MainActivity提供各个实例的地方
*/
@Module
public abstract class MainActivityModule {
@Provides
static MainPresenter provideMainPresenter() {
return new MainPresenter();
}
}
最后我们还需要在Application中初始化我们的全局注入声明:
/**
* Application 拥有很多 Activity,这就是我们实现 HasActivityInjector 接口的原因。
* 那 Activity 有多个 Fragment 呢?意思是我们需要在 Activity 中实现 HasFragmentInjector 接口吗?
* 没错,我就是这个意思!
*/
public class MyApplication extends DaggerApplication {
@Override
public void onCreate() {
super.onCreate();
MultiDex.install(this);
}
@Override
protected AndroidInjector extends DaggerApplication> applicationInjector() {
AppComponent appComponent = DaggerAppComponent.builder().application(this).build();
appComponent.inject(this);
return appComponent;
}
}
优化后写法:
public class MyApplication extends DaggerApplication {
@Override
public void onCreate() {
super.onCreate();
MultiDex.install(this);
}
@Override
protected AndroidInjector extends DaggerApplication> applicationInjector() {
return DaggerAppComponent.builder().create(this);
}
}
这样一个Presenter中注入到Activity中的方式就完成了。最后我们把AppMoudle也写出来:
@Module
public interface AppModule {
@Binds
Context provideContext(Application application);
}
之前也提到过AppMoudle是专门为全局提供retrofit、okhttp、持久化数据库、SharedPrefs的地方。