tags: [dagger2,架构,android]
categories: dagger2
top: false
toc: true
cover: false
img: /featureImg/dagger.jpg
summary: 使用dagger.android简化代码
—-

上一章中介绍了Activities Subcomponents Multibinding的实现过程,但是多出那么多步骤还是让人有些头晕;而使用dagger.android可以简化这一过程

使用

step1

需要引入”com.google.dagger:dagger-android:${dagger_version}”
如果需要注入SupportLib中的Fragment还需要引入”com.google.dagger:dagger-android-support:${dagger_version}”
引入注解处理器”com.google.dagger:dagger-android-processor:${dagger_version}”

step2

定义一个抽象的Module类,在里面定义一个返回对应Activity使用@ContributesAndroidInjector的抽象方法
dagger.android会根据@ContributesAndroidInjector生成需要注入对应对象的SubComponent,并添加到map中

  1. @Module
  2. public abstract class ActivitysModule {
  3. @ActivityScope//指定Subcomponent的生命周期
  4. @ContributesAndroidInjector(modules = DaggerAndroidActivityModule.class)//指定DaggerAndroidActivity的Subcomponent中需要安装的Module
  5. abstract DaggerAndroidActivity bindDaggerAndroidActivity();
  6. }

这一步相当于完成了上篇文章中的step2、3、4、5,最终dagger.android会生成需要添加到map中的SubComponet.Builder

step3

将包含@ContributesAndroidInjector注解方法的Module和dagger.android提供的Module安装到AppComponent中

  1. @Component(modules = { AndroidInjectionModule.class,
  2. AndroidSupportInjectionModule.class,
  3. ActivitysModule.class,...})
  4. public interface AppComponent {
  5. void inject(RealApplication application);
  6. }

step4

在Application中实现HasActivityInjector接口

  1. public class RealApplication extends BaseApplication implements HasActivityInjector {
  2. @Inject
  3. DispatchingAndroidInjector<Activity> activityInjector;
  4. @Override
  5. public void onCreate() {
  6. super.onCreate();
  7. DaggerAppComponent.builder()
  8. .baseAppModule(new BaseAppModule(this))
  9. .build().inject(this);
  10. }
  11. @Override
  12. public AndroidInjector<Activity> activityInjector() {
  13. return activityInjector;
  14. }
  15. }

dagger.android还可以支持其他三大组件以及Fragment的注入,具体可以查看DaggerApplication的源码

step5

在activity中完成注入

  1. @Override
  2. protected void onCreate(@Nullable Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4. AndroidInjection.inject(this);
  5. }

原理解析

看看AndroidInjection.inject(this)到底干了啥

  1. public static void inject(Activity activity) {
  2. checkNotNull(activity, "activity");
  3. Application application = activity.getApplication();
  4. if (!(application instanceof HasActivityInjector)) {
  5. throw new RuntimeException(
  6. String.format(
  7. "%s does not implement %s",
  8. application.getClass().getCanonicalName(),
  9. HasActivityInjector.class.getCanonicalName()));
  10. }
  11. //因为application实现了HasActivityInjector,所以可以得到一个
  12. AndroidInjector<Activity> activityInjector =
  13. ((HasActivityInjector) application).activityInjector();
  14. checkNotNull(activityInjector, "%s.activityInjector() returned null", application.getClass());
  15. activityInjector.inject(activity);
  16. }
  • application中被注入的是DispatchingAndroidInjector
  • 其中持有了Map<Class<? extends T>, Provider<AndroidInjector.Factory<? extends T>>> injectorFactories;相当于SubComponent.Builder的map,
  • DispatchingAndroidInjector实现了 AndroidInjector,这里的inject(T instance);是通过获取AndroidInjector.Factory构造可直接注入的AndroidInjector间接完成的注入
  1. public interface AndroidInjector<T> {
  2. void inject(T instance);
  3. interface Factory<T> {
  4. AndroidInjector<T> create(T instance);
  5. }
  6. abstract class Builder<T> implements AndroidInjector.Factory<T> {
  7. @Override
  8. public final AndroidInjector<T> create(T instance) {
  9. seedInstance(instance);
  10. return build();
  11. }
  12. @BindsInstance
  13. public abstract void seedInstance(T instance);
  14. public abstract AndroidInjector<T> build();
  15. }
  16. }

AndroidInjector就比较好理解了,它其实就是一个SubComponent的下层接口,而AndroidInjector.Factory就是它的Builder

优点

大大简化了Multibindings的实现过程

缺点

  • 因为Multibindings的整个原理是面向抽象的,所以基于Multibindings的dagger.android也无法使用AndroidInjector.Factory提供其他的参数作为依赖的基础
  • dagger.android只支持四大组件和Fragment,对于ViewModel这种对于Multibindings有强烈需求的对象还不支持(立个flag,有官方支持应该也快了)

相关文章

dagger2从入门到放弃-概念
dagger2从入门到放弃-最基础的用法介绍
dagger2从入门到放弃-Component的继承体系、局部单例
dagger2从入门到放弃-ActivityMultibindings
dagger2从入门到放弃-dagger.android
dagger2从入门到放弃-其他用法
dagger2从入门到放弃-多模块项目下dagger的使用
dagger2从入门到放弃-为何放弃

示例代码

DaggerInAction 欢迎star master分支上最新的代码可能会比当前文章的示例代码稍微复杂点,提交记录里包含了每一步的迭代过程,可以顺藤摸瓜