直接采用@声明的方式,而不是new,依赖注入干嘛的,省却new的,就是为了不用new 用的,但是使用场景受限,
通过构造器或者其他方法传入依赖的对象就是依赖注入,这样就不需要在一个模块中去创建另外一个模块了。对象是在别的地方被创建然后通过构造器传入依赖它的对象中
你可以把他想象成一个这样的模块,它负责构造所有其他模块的实例,并且传入这些模块的依赖。现在我们的应用程序中只有一个入口来负责创建所有模块的实例,而这个入口完全在我们的控制下。
Dagger是 一个完全为低端设备设计的依赖注入器。绝大多数的依赖注入器都是基于反射来实现的。反射的确很酷,但是在低端设备上执行反射的效率太低。Dagger使用 的是预编译技术来创建所有依赖的类。这样就避免了使用反射。Dagger虽然没有其他的依赖注入框架强大,但它是效率最高的。
activity.MainActivity cannot be provided without an @Inject constructor or from an @Provides-annotated method.
因为Activity正常情况下不会编写构造函数,因而也就无法通过@Inject构造函数实例化,只能通过@Provides提供,所以,component在依赖Module里面必须相应的提供,创建Module的时候,也必须把Activity引用传递过去。因为依赖是层层递归的,因此必要要将需要的依赖模块实例化。
public interface AppComponent {
Application getApplication();
ApiService getApiService();
User getUser();
}
根据返回值,方法名随便写
scope只是为编译提供一些约束,如果scope不一一对应是无法编译通过的,singleton也仅仅是一个scope的annotation,本身没有实现单利的能力,仍然可以实现度多个component与module,只是application的实例要通过类似单利的模型来提供,总的来说,还是程序自身来保证单利模式。
@SuppressWarnings("unchecked") // cast only happens when result comes from the factory
@Override
public T get() {
// double-check idiom from EJ2: Item 71
Object result = instance;
if (result == UNINITIALIZED) {
synchronized (this) {
result = instance;
if (result == UNINITIALIZED) {
instance = result = factory.get();
}
}
}
return (T) result;
}
DaggerDaggerActivityComponent
private Provider<String> provideClassNameProvider;
private Provider<User> provideUserProvider;
private Provider<Activity> provideDaggerActivityProvider;
private Provider<DaggerActivityPresenter> daggerActivityPresenterProvider;
private MembersInjector<DaggerActivity> daggerActivityMembersInjector;
private MembersInjector<MainActivity> mainActivityMembersInjector;
private void initialize(final Builder builder) {
this.provideClassNameProvider = ScopedProvider.create(DaggerActivityModule_ProvideClassNameFactory.create(builder.daggerActivityModule));
this.provideUserProvider = ScopedProvider.create(DaggerActivityModule_ProvideUserFactory.create(builder.daggerActivityModule));
this.provideDaggerActivityProvider = ScopedProvider.create(DaggerActivityModule_ProvideDaggerActivityFactory.create(builder.daggerActivityModule));
this.daggerActivityPresenterProvider = DaggerActivityPresenter_Factory.create(provideDaggerActivityProvider);
this.daggerActivityMembersInjector = DaggerActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideClassNameProvider, provideUserProvider, daggerActivityPresenterProvider);
this.mainActivityMembersInjector = MainActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideUserProvider);
}
provide之间是相互依赖的,Provide应该是先生成不需要参数的,再生成需要参数的
@Override
public void Inject(DaggerActivity activity) {
daggerActivityMembersInjector.injectMembers(activity);
}
@Override
public void Inject(MainActivity activity) {
mainActivityMembersInjector.injectMembers(activity);
}
如果一个类在同一方式下有多个创建类的方法的时候,Component会选取哪个方法来创建这个类的实例呢?举个例子
@Module
public class Module{
@Provides
A provideA(){
return A();
}
@provides
A provideOtherA(){
return A();
}
} 如果我们按照上面这样写,Dagger2在编译的时候就会报错,那么我们改如何解决呢?这时候就需要用到@Qualifier了,我们可以用这个注解给不同的创建实例的方法进行标识并加以区分。
@Module
public class Module{
@Named("firstA")
@Provides
A provideFirstA(){
return A();
}
@Named("secondA")
@provides
A provideSecondA(){
return A();
}
} @Named是Dagger2对于@Qualifier一个默认实现,我们也可以自定义,比如@ForApplication和@ForAcitivity来标识不同的Context
@Qualifier @Documented @Retention(RUNTIME) public @interface Named {
/** The name. */
String value() default ""; } 这样,通过@Named我们就可以区分不同的实例了
public class Human{
@Inject
@Named("firstA")
A firstA;
@Named("secondA")
@provides
A secondA;
}
使用Android依赖注入工具Dagger(一)
Android:dagger2让你爱不释手-基础依赖注入框架篇
Android:dagger2让你爱不释手
Android:dagger2让你爱不释手
Android:dagger2让你爱不释手