Dagger2 Activity的注入

架构图:

Dagger2 Activity的注入_第1张图片

现在有个需求,就是在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 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 applicationInjector() {
        return DaggerAppComponent.builder().create(this);
    }

}

这样一个Presenter中注入到Activity中的方式就完成了。最后我们把AppMoudle也写出来:

@Module
public interface AppModule {
    @Binds
    Context provideContext(Application application);
}

之前也提到过AppMoudle是专门为全局提供retrofit、okhttp、持久化数据库、SharedPrefs的地方。

 

 

 

 

你可能感兴趣的:(android)