Dagger2
什么是依赖注入 依赖注入的好处
http://blog.csdn.net/hsk256/article/details/51530667
http://blog.csdn.net/u010961631/article/details/72626134
http://blog.csdn.net/android_study_ok/article/details/52440464
dependencies方式让Component之间更加独立,结构更加清晰,也更利于解耦。
dependencies中Component强调的是在子类Component依赖于某个Component(子类为主角),而Subcomponent中强调的则是在父类Component中提供某个子类的Component(父类为主角)。
Lazy延时加载就是,需要调用两遍才能得到最终的结果,和懒汉模式不一样。
- 作用域scope需要自定义
- 限定符@Named("app") 根据Class作为key,存在class重复时用@Name标示
- 依赖入参怎么办?注入的实例、被注入的引用。实例化对象所需参数分两类:手动传入的、moudle提供的。
- component之间的关系分为:继承和依赖,对作用域、对module的作用域的影响
外界有两种使用方式,方法注入(mBindPoiComponent.inject(this);)、Provider注入( mBindPoiComponent.sp();)
private Provider<Context> provideContextProvider;
private MembersInjector<BindPoiModule> bindPoiModuleMembersInjector;
都需要在BindPoiComponent中显示声明。
答疑
-
同Component中Module内部可以共享么?
可以 -
同Component中不同Module之间可以共享么?
可以 -
依赖关系中当前和依赖跨Componet不同Module之间可以共享么?
可以,共享条件是,必须在依赖的Componet中显式的声明哪些能被其他Component使用。 -
依赖关系作用域能共享么
不能! -
继承关系中子类和父类跨Component不同Module之间可以共享么?
可以,但是要把module传递给父Component中 -
继承关系中作用域可共享么
可以 -
Module构造函数带入参的都需要手动初始化了
是的,并且如果Module内包含需要注入的属性,需要自行解决调用inject。
- 寻找目标依赖的实例的过程是,先Module再被Inject标注的构造函数
被Inject标注的构造函数,如果还用到了注入,Dagger会自动帮你注入,这点和Module有很大的不同。Inject方式,很容易在构造函数中手动调用inject(),其实是不需要的。
跨Component依赖关系,Module之间的依赖,需要依赖中对外声明后才能使用。
Module的构造函数存在入参时,如果入参实例能在Dagger依赖中找到,则由系统自动创建,找不到,则由用户初始化,否则抛出IllegalStateException异常。
public BindPoiComponent build() {
if (bindPoiModule == null) {
throw new IllegalStateException(BindPoiModule.class.getCanonicalName() + " must be set");
}
if (activiyModule == null) {
this.activiyModule = new ActiviyModule();
}
单例的实现方式,被DoubleCheck 代理保证只生产一次。生产后对被代理引用置空
this.providePresenterProvider =DoubleCheck.provider(BindPoiModule_ProvidePresenterFactory.create(builder.bindPoiModule));
/* Null out the reference to the provider. We are never going to need it again, so we
* can make it eligible for GC. */
provider = null;
Module必须手动inject,否则会发现调用mContext时发生空指针
@Module
public class BindPoiModule {
private BindPoiContact.View mView;
@Inject
@Named("app")
Context mContext;
//TODO 如何用AppContext
public BindPoiModule(BindPoiContact.View mView) {
this.mView = mView;
}
多个Component之间,使用依赖Component中的provider时,必须显性声明
this.contextProvider =
new Factory<Context>() {
private final ApplicationComponent applicationComponent = builder.applicationComponent;
@Override
public Context get() {
return Preconditions.checkNotNull(
applicationComponent.context(),
"Cannot return null from a non-@Nullable component method");
}
};
屏幕快照 2017-12-23 下午5.02.40.png