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中
@Modulepublic abstract class ActivitysModule {@ActivityScope//指定Subcomponent的生命周期@ContributesAndroidInjector(modules = DaggerAndroidActivityModule.class)//指定DaggerAndroidActivity的Subcomponent中需要安装的Moduleabstract DaggerAndroidActivity bindDaggerAndroidActivity();}
这一步相当于完成了上篇文章中的step2、3、4、5,最终dagger.android会生成需要添加到map中的SubComponet.Builder
step3
将包含@ContributesAndroidInjector注解方法的Module和dagger.android提供的Module安装到AppComponent中
@Component(modules = { AndroidInjectionModule.class,AndroidSupportInjectionModule.class,ActivitysModule.class,...})public interface AppComponent {void inject(RealApplication application);}
step4
在Application中实现HasActivityInjector接口
public class RealApplication extends BaseApplication implements HasActivityInjector {@InjectDispatchingAndroidInjector<Activity> activityInjector;@Overridepublic void onCreate() {super.onCreate();DaggerAppComponent.builder().baseAppModule(new BaseAppModule(this)).build().inject(this);}@Overridepublic AndroidInjector<Activity> activityInjector() {return activityInjector;}}
dagger.android还可以支持其他三大组件以及Fragment的注入,具体可以查看DaggerApplication的源码
step5
在activity中完成注入
@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);AndroidInjection.inject(this);}
原理解析
看看AndroidInjection.inject(this)到底干了啥
public static void inject(Activity activity) {checkNotNull(activity, "activity");Application application = activity.getApplication();if (!(application instanceof HasActivityInjector)) {throw new RuntimeException(String.format("%s does not implement %s",application.getClass().getCanonicalName(),HasActivityInjector.class.getCanonicalName()));}//因为application实现了HasActivityInjector,所以可以得到一个AndroidInjector<Activity> activityInjector =((HasActivityInjector) application).activityInjector();checkNotNull(activityInjector, "%s.activityInjector() returned null", application.getClass());activityInjector.inject(activity);}
- application中被注入的是
DispatchingAndroidInjector - 其中持有了
Map<Class<? extends T>, Provider<AndroidInjector.Factory<? extends T>>> injectorFactories;相当于SubComponent.Builder的map, - DispatchingAndroidInjector实现了
AndroidInjector,这里的inject(T instance);是通过获取AndroidInjector.Factory构造可直接注入的AndroidInjector间接完成的注入
public interface AndroidInjector<T> {void inject(T instance);interface Factory<T> {AndroidInjector<T> create(T instance);}abstract class Builder<T> implements AndroidInjector.Factory<T> {@Overridepublic final AndroidInjector<T> create(T instance) {seedInstance(instance);return build();}@BindsInstancepublic abstract void seedInstance(T instance);public abstract AndroidInjector<T> build();}}
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分支上最新的代码可能会比当前文章的示例代码稍微复杂点,提交记录里包含了每一步的迭代过程,可以顺藤摸瓜
