前言
在使用Dagger2进行Android开发时,不可避免的问题是我们需要实例化一些Android系统的类,比如Activity或者Fragment。最理想的情况是Dagger能够创建所有需要依赖注入的对象,但事实上,我们不得不在容器的声明周期中添加大量的重复性代码,这些模版代码虽然相近但是却又不能封装到基类里面,那应该怎么呢?
正因为有着种种问题所以就有了Dagger-Android的出现。
具体实现
引入依赖
由于需要使用到DaggerAndroid相关的一些内容,就需要引入dagger-android的依赖。
1 2 3 4 5 6 7 8 | // dagger的引用 implementation 'com.google.dagger:dagger:2.24' annotationProcessor 'com.google.dagger:dagger-compiler:2.24' // 如果要使用dagger-android则引用 implementation 'com.google.dagger:dagger-android:2.24' implementation 'com.google.dagger:dagger-android-support:2.24' // if you use the support libraries annotationProcessor 'com.google.dagger:dagger-android-processor:2.24' |
创建Activity基类
一般的我们都需要将Activity的共同部分抽离出来封装到BaseActivity中去:
1 2 3 4 5 6 7 8 | public class BaseActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { // 一行代码建立连接,其背后的逻辑都由DaggerAndroid所封装 AndroidInjection.inject(this); super.onCreate(savedInstanceState); } } |
创建BaseActivityComponent:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // 一定要引入AndroidInjectionModule @Subcomponent(modules = { AndroidInjectionModule.class, }) // 接口继承AndroidInjector,将需要进行绑定的BaseActivity作为泛型传入 public interface BaseActivityComponent extends AndroidInjector<BaseActivity> { // 使用Factory的方式实现构造 // 在继承的AndroidInjector.Factory<BaseActivity>接口中,已经将方法实现,所以这里不需要在添加其它方法 // 注意在之前的版本中是可以通过Builder的方式实现构造的,但是现在已经被废弃 @Subcomponent.Factory interface Factory extends AndroidInjector.Factory<BaseActivity> { } } |
建立与Application的连接
首先来定义Application的Component:
1 2 3 4 5 6 7 8 9 10 | // 一定要引入AndroidInjectionModule和AndroidSupportInjectionModule // ActivityManagerModule是作为对ActivityModule进行管理的一个Module @Component(modules = { AndroidInjectionModule.class, AndroidSupportInjectionModule.class, ActivityManagerModule.class }) public interface BaseApplicationComponent { void inject(BaseApplication application); } |
创建BaseApplication:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | // 实现HasAndroidInjector接口 public class BaseApplication extends Application implements HasAndroidInjector { // 将DispatchingAndroidInjector注入 @Inject DispatchingAndroidInjector<Object> dispatchingAndroidInjector; @Override public void onCreate() { super.onCreate(); // 建立连接 DaggerBaseApplicationComponent.create().inject(this); } // 提供给HasAndroidInjector做处理 @Override public AndroidInjector<Object> androidInjector() { return dispatchingAndroidInjector; } } |
创建ActivityModule管理类
1 2 3 4 5 6 7 8 9 | @Module(subcomponents = { BaseActivityComponent.class }) public abstract class ActivityManagerModule { // 所有需要进行注入操作的Activity只要添加对应的两行代码即可 @ContributesAndroidInjector(modules = FirstActivityModule.class) abstract FirstActivity contributeFirstActivitytInjector(); } |
创建业务的Activity
1 2 3 4 5 | public class FirstPresenter { public void log() { Log.d("Dagger测试", "获取到MainPresenter了"); } } |
1 2 3 4 5 6 7 8 | // 实现业务的Module提供所要的依赖 @Module public class FirstActivityModule { @Provides FirstPresenter providerMainPresenter() { return new FirstPresenter(); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // 继承BaseActivity,无需实现DaggerXXX类的注册过程 public class FirstActivity extends BaseActivity { @Inject FirstPresenter mFirstPresenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mFirstPresenter.log(); } } |
这样就完成了通过DaggerAndroid实现的依赖注入,这种方式将Dagger的注入实现过程隐藏了起来,在外部只需要知道所要调用的对象是什么就可以了。
关于Dagger和DaggerAndroid之间的选择
怎么说呢,相比于DaggerAndroid来说Dagger用的时间更久,或者说DaggerAndroid一直知道有这个东西却没有去学习和使用它。
关于在项目中的使用,我还是更加倾向于Dagger,虽然它会在业务Activity中新创建很多东西,但是对于一般的开发者来说Dagger更容易理解和接受,所以我在进行框架搭建的时候会以Dagger作为注入对象,可能后期会使用DaggerAndroid去进行改造也说不定。
关于Dagger和DaggerAndroid之间的选择还是看开发者自己吧,觉得哪一种更加方便就使用哪一种。