上一章中介绍了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中
@Module
public abstract class ActivitysModule {
@ActivityScope//指定Subcomponent的生命周期
@ContributesAndroidInjector(modules = DaggerAndroidActivityModule.class)//指定DaggerAndroidActivity的Subcomponent中需要安装的Module
abstract 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 {
@Inject
DispatchingAndroidInjector<Activity> activityInjector;
@Override
public void onCreate() {
super.onCreate();
DaggerAppComponent.builder()
.baseAppModule(new BaseAppModule(this))
.build().inject(this);
}
@Override
public AndroidInjector<Activity> activityInjector() {
return activityInjector;
}
}
dagger.android还可以支持其他三大组件以及Fragment的注入,具体可以查看DaggerApplication
的源码
step5
在activity中完成注入
@Override
protected 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> {
@Override
public final AndroidInjector<T> create(T instance) {
seedInstance(instance);
return build();
}
@BindsInstance
public 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分支上最新的代码可能会比当前文章的示例代码稍微复杂点,提交记录里包含了每一步的迭代过程,可以顺藤摸瓜