Dagger2转换为android.dagger

时间:2018-07-18 10:18:10

标签: android dagger-2 dagger

我研究了一些有关新的dagger.android方法的教程,但是做得不好。我使用子组件生成器构建了一个简单的教程,但无法将其转换为新方法。所有教程和文章都将必需的部分留空。

此示例出于学习目的,可能不适合实际情况,我仅打算实现字段注入,而构造函数注入可能更合适。

范围

@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface ActivityScope {
}   

父组件

@Component(modules = ApplicationModule.class)
@Singleton
public interface ApplicationComponent {

    // Calls SubComponent Builder from MainActivity using ApplicationComponent
    ToastMakerSubComponent.Builder toastMakerBuilder();
}

父模块,我没有在应用模块中使用@BindsInstance来学习不同的方法

@Module(subcomponents = {ToastMakerSubComponent.class})
public class ApplicationModule {

    private Context context;

    public ApplicationModule(Context context) {
        this.context = context;
    }

    @Provides
    @Singleton
    SharedPreferences provideSharedPreferences() {
        System.out.println("ApplicationModule context: " + context);
        return context.getSharedPreferences("PrefName", Context.MODE_PRIVATE);
    }
}

子组件

@ActivityScope
@Subcomponent(modules = {ToastMakerModule.class})
public interface ToastMakerSubComponent {
    void inject(MainActivity mainActivity);

    /*
     Builder is called from Parent Component,
      and parent component is called from scope(Activity, Fragment, etc.)
      */
    @Subcomponent.Builder
    interface Builder {

        ToastMakerSubComponent build();

        @BindsInstance
        Builder context(Context context);
    }
}

子组件模块

@Module
public class ToastMakerModule {

    @ActivityScope
    @Provides
    ToastMaker provideToastMaker(Context context) {
        System.out.println("ToastMakerModule context: " + context);
        return new ToastMaker(context);
    }
}

实例化MyApplication内部的ApplicationComponent

 mApplicationComponent = DaggerApplicationComponent
                .builder()
                .applicationModule(new ApplicationModule(getApplicationContext()))
                .build();

并在Activity中获取子组件

ApplicationComponent applicationComponent = ((MyApplication) getApplication()).getApplicationComponent();

ToastMakerSubComponent toastMakerSubComponent = applicationComponent
        .toastMakerBuilder()
        .context(this)
        .build();

toastMakerSubComponent.inject(this);

在遵循thisthisthis教程之后,我将以下内容构建为

@Component(modules = ApplicationModule.class)
@Singleton
public interface ApplicationComponent {
// What should i put here ???

}

父模块,但我不知道如何提供provideSharedPreferences

@Module(subcomponents = {ToastMakerSubComponent.class})
abstract class ApplicationModule {

    @Binds
    @IntoMap
    @ActivityKey(MainActivity.class)
    abstract AndroidInjector.Factory<? extends MainActivity>
    bindYourActivityInjectorFactory(ToastMakerSubComponent.Builder builder);

}

缺少子组件ToastMakerSubComponent build();@BindsInstance Builder context(Context context);,我应该如何将它们添加到此组件中。

@ActivityScope
@Subcomponent(modules = {ToastMakerModule.class})
public interface ToastMakerSubComponent extends AndroidInjector<MainActivity> {
    // ??? Is this required?
    void inject(MainActivity mainActivity);

    @Subcomponent.Builder
     abstract class Builder extends AndroidInjector.Builder<MainActivity> {
         ???
    }
}

我还看到@ContributesAndroidInjector,在此示例中它适合哪里?

1 个答案:

答案 0 :(得分:2)

以下是变化的地方:https://www.diffchecker.com/3IL8UQ7P

使应用程序组件扩展AndroidInjector<MyApplication>并包括AndroidSupportInjectionModule

@Component(modules = {ApplicationModule.class, AndroidSupportInjectionModule.class})
@Singleton
public interface ApplicationComponent extends AndroidInjector<MyApplication> {

}

使子组件扩展AndroidInjector<MainActivity>和构建器AndroidInjector.Builder<MainActivity>,并使用seedInstance@BindsInstance方法提供参数。

@ActivityScope
@Subcomponent(modules = {ToastMakerModule.class})
public interface ToastMakerSubComponent extends AndroidInjector<MainActivity> {

    @Subcomponent.Builder
    abstract class Builder extends AndroidInjector.Builder<MainActivity> {

        @Override
        public void seedInstance(MainActivity instance) {
            context(instance);
        }

        @BindsInstance
        public abstract Builder context(Context context);
    }
}

将子组件构建器的绑定添加到应用程序组件中安装的模块:

@Module(subcomponents = {ToastMakerSubComponent.class})
public abstract class ApplicationModule {

    private Context context;

    public ApplicationModule(Context context) {
        this.context = context;
    }

    @Provides
    @Singleton
    SharedPreferences provideSharedPreferences() {
        System.out.println("ApplicationModule context: " + context);
        return context.getSharedPreferences("PrefName", Context.MODE_PRIVATE);
    }

    @Binds
    @IntoMap
    @ActivityKey(MainActivity.class)
    abstract AndroidInjector.Factory<? extends Activity> bindMainActivityFactory(ToastMakerSubComponent.Builder builder);
}

让框架类扩展Dagger*对应类,或者在不能使用继承的情况下实现Has*Injector接口

public class MyApplication extends DaggerApplication {

    @Override
    protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
        return DaggerApplicationComponent.create();
    }
}

public class MainActivity extends DaggerAppCompatActivity {

    @Inject
    SharedPreferences sharedPreferences;

    @Inject
    ToastMaker toastMaker;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        toastMaker.showToast("sharedPreferences " + sharedPreferences);
    }
}