一、什么是依赖注入
依赖注入(Dependency Injection,简称 DI) 是用于实现控制反转Inversion of Control,缩写为 IoC)的最常见的方式之一。
控制反转是面向对象变成中的一种设计院子,用以降低代码之间的耦合度。控制反转的基本思想是:借助“第三方”实现具有依赖关系的对象之间的解耦。一开始是对象A对对象B具有依赖关系,对象A主动地创建对象B,对象A有主动控制权,实现了IOC后,对象A依赖于Ioc容器,对象A被动地接受IOC容器提供的对象B实例,由主动变被动。
依赖注入就是将一个对象的实例传入到另一个对象中去。依赖注入是一种设计模式,降低依赖和被依赖对象之间的耦合,方便扩展和单元测试。
依赖注入的常见实现方式:
- 基于构造函数,在构造对象时注入所依赖的对象
public class Police {
public Police(Gun gun){
this.gun = gun;
}
}
- 基于set方法,让外部容器传入所依赖的实例
public class Police {
public void setGun(Gun gun){
this.gun = gun;
}
}
- 基于接口,使用接口setter方法提供
public class Police implements GunInjector{
@Override
public void injectCar(Gun gun) {
this.gun = gun
}
}
- 基于注解实现,如Dagger2 的@Inject注解
public class Police {
@Inject
Gun gun;
}
Dagger2依赖注入的基本使用
引入Dagger2
在build.gradle中添加依赖
//dagger 2
implementation 'com.google.dagger:dagger:2.16'
annotationProcessor 'com.google.dagger:dagger-compiler:2.16'
Dagger2 依赖注入的构成:
1、目标类中 需要注入的实例 用@Inject标注。
如下,Police类中的属性Gun 和 Uniform需要注入。
public class Police {
@Inject
Gun gun;
@Inject
Uniform uniform;
}
对象会生成Police_MembersInjector类,继承自MembersInjector
@Generated(
value = "dagger.internal.codegen.ComponentProcessor",
comments = "https://google.github.io/dagger"
)
public final class Police_MembersInjector implements MembersInjector {
private final Provider gunProvider;
private final Provider uniformProvider;
public Police_MembersInjector(Provider gunProvider, Provider uniformProvider) {
this.gunProvider = gunProvider;
this.uniformProvider = uniformProvider;
}
public static MembersInjector create(
Provider gunProvider, Provider uniformProvider) {
return new Police_MembersInjector(gunProvider, uniformProvider);
}
@Override
public void injectMembers(Police instance) {
injectGun(instance, gunProvider.get());
injectUniform(instance, uniformProvider.get());
}
public static void injectGun(Police instance, Gun gun) {
instance.gun = gun;
}
public static void injectUniform(Police instance, Uniform uniform) {
instance.uniform = uniform;
}
}
2、提供依赖对象实例的工厂类。
有两种方式:
(1)用@Inject 标注构造函数,提供被依赖对象的工厂类。
public class Gun {
@Inject
public Gun(){
}
}
对应会生成Gun_Factory工厂类,通过get()方法产生依赖对象实例
@Generated(
value = "dagger.internal.codegen.ComponentProcessor",
comments = "https://google.github.io/dagger"
)
public final class Gun_Factory implements Factory {
private static final Gun_Factory INSTANCE = new Gun_Factory();
@Override
public Gun get() {
return provideInstance();
}
public static Gun provideInstance() {
return new Gun();
}
public static Gun_Factory create() {
return INSTANCE;
}
public static Gun newGun() {
return new Gun();
}
}
(2)通过 @Moudle 和@Providers注解配合使用。
- 此方法主要适用于第三方类库 等无法修改构造方法的场景。
- @Module方式的 要优先于 @inject的方式 注入实例
@Module
public class UniFormModule {
@Provides
Uniform provideUniform(){
return new Uniform();
}
}
public class Uniform {
}
对应会生成UniFormModule_ProvideUniformFactory类,通过get()方法得到。
@Generated(
value = "dagger.internal.codegen.ComponentProcessor",
comments = "https://google.github.io/dagger"
)
public final class UniFormModule_ProvideUniformFactory implements Factory {
private final UniFormModule module;
public UniFormModule_ProvideUniformFactory(UniFormModule module) {
this.module = module;
}
@Override
public Uniform get() {
return provideInstance(module);
}
public static Uniform provideInstance(UniFormModule module) {
return proxyProvideUniform(module);
}
public static UniFormModule_ProvideUniformFactory create(UniFormModule module) {
return new UniFormModule_ProvideUniformFactory(module);
}
public static Uniform proxyProvideUniform(UniFormModule instance) {
return Preconditions.checkNotNull(
instance.provideUniform(), "Cannot return null from a non-@Nullable @Provides method");
}
}
(3)通过 @Moudle 和@Binds注解 提供注入
@Binds 是@provider的替代。
@provider 修饰的方法的方法体必须返回一个实体类。
而 @Binds 修饰的方法A 返回一个接口,方法A 的参数必须是接口的实现类。方法A是抽象的,所以不需有方法体。
同时方法A中的参数(如SplashViewModel) 必须是可以可供注入的(@Module和@Provider方式提供了注入,或者其构造方法添加@Inject方式提供了注入)
@Module
abstract class ViewModelModule {
@Binds
abstract fun bindSplashModel(model: SplashViewModel): ViewModel
}
如上声明后,就可以直接获取到SplashViewModel的注入对象了。
另外@Binds 还可以和@IntoMap (或IntoSet)结合使用.
如下所示,注入的SplashViewModel对象会放入到一个Map结构中。
该Map结构 可直接为其他对象提供注入(自动生成的Map对象自动成为可注入对象)。
@Module
abstract class ViewModelModule {
@Binds
@IntoMap
@ViewModelKey(SplashViewModel::class)
abstract fun bindSplashModel(model: SplashViewModel): ViewModel
}
3、提供@Component 修饰的接口XXXComponent接口,并提供inject()注入方法
Component 一方面连接着目标类,另一方面连接着 被依赖对象的工厂类,通过inject()方法将目标类中的对象方法 进行实例注入。
@Component(modules = UniFormModule.class)
public interface PoliceComponent {
public void inject(Police police);
}
对应生成DaggerPoliceComponent类,DaggerPoliceComponent.Builder类。
通过inject方法,将提供依赖实例的Factory类于目标类对应的属性相关联。
@Generated(
value = "dagger.internal.codegen.ComponentProcessor",
comments = "https://google.github.io/dagger"
)
public final class DaggerPoliceComponent implements PoliceComponent {
private UniFormModule uniFormModule;
private DaggerPoliceComponent(Builder builder) {
initialize(builder);
}
public static Builder builder() {
return new Builder();
}
public static PoliceComponent create() {
return new Builder().build();
}
@SuppressWarnings("unchecked")
private void initialize(final Builder builder) {
this.uniFormModule = builder.uniFormModule;
}
@Override
public void inject(Police police) {
injectPolice(police);
}
private Police injectPolice(Police instance) {
Police_MembersInjector.injectGun(instance, new Gun());
Police_MembersInjector.injectUniform(
instance, UniFormModule_ProvideUniformFactory.proxyProvideUniform(uniFormModule));
return instance;
}
public static final class Builder {
private UniFormModule uniFormModule;
private Builder() {}
public PoliceComponent build() {
if (uniFormModule == null) {
this.uniFormModule = new UniFormModule();
}
return new DaggerPoliceComponent(this);
}
public Builder uniFormModule(UniFormModule uniFormModule) {
this.uniFormModule = Preconditions.checkNotNull(uniFormModule);
return this;
}
}
}
二、几个特殊概念
1、Lazy (延迟注入)
有时我们希望注入的依赖在使用时在完成初始化,可以加快加载速度,这是可以使用Layz
public class Man {
@Inject
Lazy lazyCar;
public void goWork() {
...
lazyCar.get().go(); // lazyCar.get() 返回 Car 实例
...
}
}
2、Provider 注入
有时候我们不仅仅是注入单个实例,我们需要多个实例,这是可以使用Provider
public class CarFactory {
@Inject
Provider carProvider;
public List makeCar(int num) {
...
List carList = new ArrayList(num);
for (int i = 0; i < num; i ++) {
carList.add(carProvider.get());
}
return carList;
}
}
3、Qualifier(限定符)
注入迷失问题:
如果 CarModule 提供了两个生成 Car 实例的 provide 方法,Dagger2 就不知道用哪个provider来注入了。这称为注入迷失问题。
@Module
public class CarModule {
@Provides
static Car provideCar1() {
return new Car1();
}
@Provides
static Car provideCar2() {
return new Car2();
}
// Car1 和 Car2 是 Car 的两个子类
}
@Qualifier注解就是用来解决这个问题,使用注解来确定使用哪种 provide 方法。
自定义的@Named注解,你也可以用自定义的其他 Qualifier 注解。
@Qualifier
@Documented
@Retention(RUNTIME)
public @interface Named {
String value() default "";
}
在 provide 方法上加上@Named注解,用来区分
@Module
public class CarModule {
@Provides
@Named("car1")
static Car provideCar1() {
return new Car1();
}
@Provides
@Named("car2")
static Car provideCar2() {
return new Car2();
}
}
还需要在 Inject 注入的地方加上@Named注解,表明需要注入的是哪一种 Car:
public class Man {
@Inject
@Named("car1")
Car car;
...
}
Qualifier(限定符)的作用相当于起了个区分的别名。
4、Scope(作用域)
Scope 是用来确定注入的实例的生命周期的。
如果没有使用 Scope 注解,Component 每次调用 Module 中的 provide 方法或 Inject 构造函数生成的工厂时都会创建一个新的实例,而使用 Scope 后可以复用之前的依赖实例。
当Component 与 Module、目标类(需要被注入依赖)使用 Scope 注解绑定时,意味着 Component 对象持有绑定的依赖实例的一个引用直到 Component 对象本身被回收。也就是作用域的原理,其实是让生成的依赖实例的生命周期与 Component 绑定,Scope 注解并不能保证生命周期,要想保证赖实例的生命周期,需要确保 Component 的生命周期。
自定义一个Scope
@Documented
@Retention(RUNTIME)
@Scope
public @interface MyScope {}
@Module
public class CarModule {
@Provides
@MyScope
static Car provideCar() {
return new Car();
}
}
@MyScope
@Component(modules = CarModule.class)
public interface ManComponent {
void injectMan(Man man);
}
Module 中 provide 方法中的 Scope 注解必须和 与之绑定的 Component 的 Scope 注解一样,否则作用域不同会导致编译时会报错。
- Scope 作用域的本质:Component 间接持有依赖实例的引用,把实例的作用域与 Component 绑定,它们不是同年同月同日生,但是同年同月死。
- Component 可以同时被多个 Scope 标记。即 Component 可以和多个 Scope 的 Moudle 或目标类绑定。
4、Reusable Scope
reusable 可以缓存之前的实例,可以复用之前的实例,不想关心与之绑定是什么 Component。
reusable 作用域不关心绑定的 Component,Reusable 作用域只需要标记目标类或 provide 方法,不用标记 Component。
5、Binding Instances
@BindsInstance注解,只能在 Component.Builder 中使用,用于在创建Component的时候绑定依赖实例。
并且在调用build()创建 Component 之前,所有@BindsInstance方法必须先调用。
@ActivityScope
@Component
public interface HomeActivityComponent {
@Component.Builder
interface Builder {
@BindsInstance
Builder activity(Activity activity);
HomeActivityComponent build();
}
}
三、Component 的组织关系:(dependencies)依赖关系、(subcomponent)继承关系
1、依赖关系 :一个 Component 依赖其他 Compoent 公开的依赖实例,用 Component 中的dependencies声明。
- 被依赖的 Component 需要把暴露的依赖实例用显式的接口声明,如上面的Car car(),我们只能使用朋友愿意分享的东西。
- 依赖关系中的 Component 的 Scope 不能相同,因为它们的生命周期不同。
如下:
@ManScope
@Component(modules = CarModule.class)
public interface ManComponent {
void inject(Man man);
Car car(); //必须向外提供 car 依赖实例的接口,表明 Man 可以借 car 给别人
}
@FriendScope
@Component(dependencies = ManComponent.class)
public interface FriendComponent {
void inject(Friend friend);
}
依赖注入时,需要把被依赖组件(manComponent)的对象 传递到 依赖组件(FriendComponent)中。
ManComponent manComponent = DaggerManComponent.builder()
.build();
FriendComponent friendComponent = DaggerFriendComponent.builder()
.manComponent(manComponent)
.build();
friendComponent.inject(friend);
这样Friend中的car 就和Man中的car时同一个car
2、 继承关系:
一个 Component 继承(也可以叫扩展)某 Component 提供更多的依赖。SubComponent 就是继承关系的体现。
public class Man {
@Inject
Car car;
...
}
public class Son {
@Inject
Car car;
@Inject
Bike bike;
}
Son 可以开他爸爸 Man 的车 car,也可以骑自己的自行车 bike。
SonComponent 是在 FatherComponent之中的,SonComponent 子承父业,可以访问 FatherComponent 的依赖。 而FatherComponent 只知道 SonComponent 是它的 child Component,可以访问 SubComponent.Builder,却无法访问 SubComponent 中的依赖。
@Module(subcomponents = SonComponent.class)
public class FatherModule {
@Provides
@FatherScope
static Car provideCar(){
return new Car();
}
}
@FatherScope
@Component(modules = FatherModule.class)
public interface FatherComponent {
void inject(Man man);
SonComponent.Builder sonComponent(); // 增加一个方法,用来创建 Subcomponent。
}
@Documented
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface FatherScope {
}
public class Bike {
}
@Module
public class BikeModule {
@Provides
@SonScope
Bike provideBike(){
return new Bike();
}
}
public class Son {
@Inject
public Car car;
@Inject
public Bike bike;
}
@SonScope
@Subcomponent(modules = BikeModule.class)
public interface SonComponent {
void inject(Son son);
@Subcomponent.Builder
interface Builder{
SonComponent build();
}
}
@Scope
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SonScope {
}
如何定义Subcomponent?
- 用@Subcomponent 标记SonComponent类
-同时SonComponent类中 定义 @Subcomponent.Builder接口,声明SonComponent build();
@SonScope
@Subcomponent(modules = BikeModule.class)
public interface SonComponent {
void inject(Son son);
@Subcomponent.Builder
interface Builder{
SonComponent build();
}
}
如何表明SubComponent是属于哪个Parent Component的的?
需要在 parent Component 依赖的 Module 中的subcomponents加上 SubComponent 的 class
@Module(subcomponents = SonComponent.class)
public class FatherModule {
@Provides
@FatherScope
static Car provideCar(){
return new Car();
}
}
SubComponent 编译时不会生成 DaggerXXComponent类文件,
其生代码实现位于DaggerFatherComponenet内部,以内部类的形式存在。
public final class DaggerFatherComponent implements FatherComponent {
private Provider provideCarProvider;
private DaggerFatherComponent(Builder builder) {
initialize(builder);
}
@Override
public SonComponent.Builder sonComponent() {
return new SonComponentBuilder();
}
private Man injectMan(Man instance) {
Man_MembersInjector.injectCar(instance, provideCarProvider.get());
return instance;
}
public static final class Builder {
private Builder() {}
public FatherComponent build() {
return new DaggerFatherComponent(this);
}
/**
* @deprecated This module is declared, but an instance is not used in the component. This
* method is a no-op. For more, see https://google.github.io/dagger/unused-modules.
*/
@Deprecated
public Builder fatherModule(FatherModule fatherModule) {
Preconditions.checkNotNull(fatherModule);
return this;
}
}
private final class SonComponentBuilder implements SonComponent.Builder {
private BikeModule bikeModule;
@Override
public SonComponent build() {
if (bikeModule == null) {
this.bikeModule = new BikeModule();
}
return new SonComponentImpl(this);
}
}
private final class SonComponentImpl implements SonComponent {
private Provider provideBikeProvider;
private SonComponentImpl(SonComponentBuilder builder) {
initialize(builder);
}
@SuppressWarnings("unchecked")
private void initialize(final SonComponentBuilder builder) {
this.provideBikeProvider =
DoubleCheck.provider(BikeModule_ProvideBikeFactory.create(builder.bikeModule));
}
@Override
public void inject(Son son) {
injectSon(son);
}
private Son injectSon(Son instance) {
Son_MembersInjector.injectCar(instance, DaggerFatherComponent.this.provideCarProvider.get());
Son_MembersInjector.injectBike(instance, provideBikeProvider.get());
return instance;
}
}
}
依赖注入代码:
Son son = new Son();
Man man = new Man();
FatherComponent fatherComponent = DaggerFatherComponent.builder().build();
SonComponent sonComponent = fatherComponent.sonComponent().build();
sonComponent.inject(son);
fatherComponent.inject(man);
Log.d("feifei---","father.car:"+man.car.hashCode()+"\n"
+"son.car:"+son.car.hashCode()
);
依赖关系 vs 继承关系
相同点:
- 两者都能复用其他 Component 的依赖
- 有依赖关系和继承关系的 Component 不能有相同的 Scope
区别点:
- 依赖关系中被依赖的 Component 必须显式地提供公开依赖实例的接口,而 SubComponent 默认继承 parent Component 的依赖
- 依赖关系会生成两个独立的 DaggerXXComponent 类,而 SubComponent 不会生成 独立的 DaggerXXComponent 类。
module 之间可以组成include 关系。
一个moduleA可以将另一个moduleB包含进来,拥有moduleB中的所有的provider.
@Module(includes = [ViewModelModule::class])
class AppModule {
}
四、 dagger.android的使用
引入dagger.android扩展库
// dagger 2
implementation "com.google.dagger:dagger:$dagger_version"
kapt "com.google.dagger:dagger-compiler:$dagger_version"
// dagger.android
implementation "com.google.dagger:dagger-android:$dagger_version"
implementation "com.google.dagger:dagger-android-support:$dagger_version"
kapt "com.google.dagger:dagger-android-processor:$dagger_version"
1、定义XXXSubComponent
/**
* 指定SearchActivitySubcomponent 继承自AndroidInjector接口
* 指定SearchActivitySubcomponent.Builder 继承自AndroidInjector.Builder
* SearchActivitySubcomponent 继承自 AppComponent,同时也就继承了AppComponenet中的所有的Provider
* 包括:AppService、DbService,FlowerBean 还有Application的provider
*/
@Subcomponent(modules = {AndroidInjectionModule.class})
public interface SearchActivitySubcomponent extends AndroidInjector {
@Subcomponent.Builder
abstract class Builder extends AndroidInjector.Builder{
}
AppService providerAppApi();
}
2、定义Application 依赖的module
如下,指定subcomponents 为 1中定义的 SearchActivitySubcomponent.class
用@Binds、@IntoMap、@ActivityKey 注释,指定ActivityModule 提供 AndroidInjector.Factory extends Activity> 的Provider,
并将SearchActivitySubcomponent.class 和SearchActivitySubcomponent.Builder 保存到一个map结构中。
@Module(subcomponents = {SearchActivitySubcomponent.class})
public abstract class ActivityModule {
/**
* @Binds的用法:
*
*当需要返回的是接口的实例时,需要用到@Binds注解
* 并要求:
* (1)方法中必须有参数且只能有一个,是接口的实现类,返回值类型是一个接口
* (2)实现类必须提供@Inject的构造或Module中的Provides形式提供
* (3)方法是抽象方法,不必写方法体
* (4)此时使用@Binds代替@Inject
*/
/**
* @IntoMap 是有注入形式初始化 map集合,Map由一系列key-value组成。
* @ActivityKey(SearchActivity.class) 指定了map中使用的Key,而value为方法的返回值。
*
*/
@Binds
@IntoMap
@ActivityKey(SearchActivity.class)
abstract AndroidInjector.Factory extends Activity> bindAndroidInjectorFactory(SearchActivitySubcomponent.Builder builder);
}
3、把module 安装到AppComponent当中
@Singleton
@Component(modules = {
AppModule.class,
ActivityModule.class,
//YourActivityModule.class,
AndroidInjectionModule.class,
})
public interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
public Builder application(Application application);
public AppComponent build();
}
void inject(MyApp application);
AppService providerAppApi();
}
4、MyApp 继承HasActivityInjector ,实现activityInjector()方法,
定义并@Inject标记注入DispatchingAndroidInjector
public class MyApp extends Application implements HasActivityInjector {
@Inject
public DispatchingAndroidInjector dispatchingActivityInjector;
@Override
public void onCreate() {
super.onCreate();
DaggerAppComponent.builder().application(this).build().inject(this);
}
@Override
public AndroidInjector activityInjector() {
return dispatchingActivityInjector;
}
}
6、最后在 Search的onCreate)() 方法中,在 super.onCreate() 之前调用 AndroidInjection.inject(this)。
public class SearchActivity extends AppCompatActivity {
@Inject
AppService appApi;
@Inject
DbService dbService;
@Override
protected void onCreate(Bundle savedInstanceState) {
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
Log.d("feifei -- ","appApi.hashCode:"+appApi.hashCode());
}
}
其实也可以在BaseActivity中调用AndroidInjection.inject(this)。
五、Android-dagger2的简化步骤
5.1、dagger的三要素
(1) 原型提供者providers:
- 构造方法 @Inject标记
public class Car {
@Inject
public Car(){
}
}
- @module + @providers module模块需要与DaggerXXXComponent绑定,告诉 DaggerXXXComponent去哪里取provider
@Module
public class CarModule {
@Provides
@ManScope
static Car provideCar(){
return new Car();
}
}
(2)Owner:需要原型的"人"。Owner中需要注入的对象,用@inject标注
main.java
public class Man {
@Inject
public Car car;
}
(3) component 装配工人:提供inject(T instance)方法,负责 从providers生产出原型,装备到owner 手中。
ManComponent.java
@Component(modules = CarModule.class)
public interface ManComponent {
void injectMain(Man man);
}
5.2、注入的触发时机
在特定的时机 调用注入代码:
Man man = new Man();
DaggerManComponent.builder().build().injectMain(man);
5.3、android-dagger简化步骤
如果 SubComponent 和其 Builder 没有其他方法或没有继承其他类型,可以使用 @ContributesAndroidInjector
@Module
public abstract class YourActivityModule {
/**
ContributesAndroidInjector 标注会自动生成
*/
@ActivityScoped
@ContributesAndroidInjector(modules = { UserModule.class})
abstract AActivity contributesYourActivityInjector();
}
- 上面@ContributesAndroidInjector 标记,自动实现了DaggerXXXComponent 注入worker,内部实现了inject(XXXActviity instance)
三要素中确定了 “原型Owner”和DaggerComponent 装配工人。
至于原型provider 提供者,可以通过构造方法用@inject修饰提供。或者为ContributesAndroidInjector 指定modules,去指定module寻找provider
@ContributesAndroidInjector(modules = { UserModule.class})
六 android-dagger actvity注入简化流程
1、MyApp 实现HasActivityInjector接口,提供activityInjector
class MyApp : Application(), HasActivityInjector {
@Inject
lateinit var dispatchingActivityAndroidInjector: DispatchingAndroidInjector
@Inject
@JvmField
var theAppApi: AppApi? = null
override fun onCreate() {
super.onCreate()
DaggerAppComponent.builder().build().injectApp(this)
Log.d("feifei","验证application的注入情况 - dispatchingAndroidInjector.size:"+dispatchingActivityAndroidInjector
+"\n,dispatchingFragmentAndroidInjector:"+dispatchingFragmentAndroidInjector
+"\n,theAppApi:"+theAppApi
)
}
override fun activityInjector(): AndroidInjector? {
return dispatchingActivityAndroidInjector
}
}
2 定义AppModule 和AppComponent,并在MyApp的onCreate()中调用注入方法
AppModule.java
@Module
public abstract class AppModule {
@Binds
abstract TheService getApiService(AppApi appApi);
}
AppComponent.java
@Component(modules = {
AndroidInjectionModule.class,
AppModule.class,
}
)
public interface AppComponent {
public void injectApp(MyApp app);
@Component.Builder
interface Builder{
AppComponent build();
}
}
MyApp.kt
override fun onCreate() {
super.onCreate()
DaggerAppComponent.builder().build().injectApp(this)
Log.d("feifei","验证application的注入情况 - dispatchingAndroidInjector.size:"+dispatchingActivityAndroidInjector
+"\n,dispatchingFragmentAndroidInjector:"+dispatchingFragmentAndroidInjector
+"\n,theAppApi:"+theAppApi
)
}
至此可以完成MyApp 中dispatchingActivityAndroidInjector的注入,只不过没有 Map
DispatchingAndroidInjector
class MyApp : Application(), HasActivityInjector , HasSupportFragmentInjector {
@Inject
lateinit var dispatchingActivityAndroidInjector: DispatchingAndroidInjector
}
public final class DispatchingAndroidInjector implements AndroidInjector {
private final Map, Provider>>
injectorFactories;
@Inject
DispatchingAndroidInjector(
Map, Provider>> injectorFactories) {
this.injectorFactories = injectorFactories;
}
}
3、定义ActivithModule,用ContributesAndroidInjector ,将所有的需要注入的Activity进行注册。
此时会为注入的activity提供provider,同时会生成一个Map
dispatchingActivityAndroidInjector
ActivityModule.java
@Module
abstract class ActivityModule {
//
//
/**
* 1、需要通过AndroidInjection.inject()进行注入的所有activity,都集中写到ActivityModule中,如下所示
* 2、@ContributesAndroidInjector 标注会自动生成DaggerXXXComponent(如DaggerMainActivityComponent),其继承自AndroidInjector(如AndroidInjector)
* 并实现了 void inject(T instance);方法(如,void inject(MainActivity instance))。
* 至此已经自动实现了dagger注入三要素中的 "组装工人worker"和 owner(如MainActivity)
* 如果自动生成的DaggerXXXComponent 中需要额外的provider才能够完成依赖注入,那可以将包含provider的module 添加给DaggerXXXComponent, 方法如下(利用modules =):
* @ContributesAndroidInjector(modules = [ThirdModule::class])标签
*/
@ContributesAndroidInjector
abstract fun contributeMain():MainActivity
@ContributesAndroidInjector
abstract fun controbuteSecond(): SecondActivity
@ContributesAndroidInjector(modules = [ThirdModule::class])
abstract fun controbuteThird(): ThirdActivity
@ContributesAndroidInjector
abstract fun controbuteFour(): FourActivity
}
4、在BaseActivity中调用 AndroidInjection.inject(this),具体触发Activitry的注入操作
open class BaseActivity : FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AndroidInjection.inject(this)
}
}
需要注意,
- 所有需要注入的Activity 需要继承BaseActivity类
- 所有需要注入的Activity 都需要在ActivityModule中进行注册
5、在Activity中 用@inject 标记需要注入的对象,并提供该对象的provider即可完成注入
public class SecondActivity extends BaseActivity {
@Inject
User mUser;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Log.d("feifei","mUser.name:"+mUser.getName());
}
}
public class User {
private String name;
@Inject
public User(){
this.name = "小美";
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
备注:
1、Fragment 和Service的注入流程与此类似
2、github示例代码:
https://github.com/feifei-123/TestDragger2
七、参考文章:
- https://www.jianshu.com/p/26d9f99ea3bb
- 轻松理解AndroidInjector
(dagger-android)三部曲
https://juejin.im/post/5cc72061e51d456e6154b4bc