android - Dagger2 转换为 android.dagger

标签 android dagger-2 dagger

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

这个例子是为了学习目的可能不适合实际情况,我只是想实现字段注入(inject),构造函数注入(inject)可能更合适。

范围

@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);

关注this之后, this , 和 this教程我构建了以下内容

@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,它适合这个例子的什么地方?

最佳答案

这是变化的差异:https://www.diffchecker.com/3IL8UQ7P

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

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

}

使子组件扩展AndroidInjector<MainActivity>和 builder 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);
    }
}

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

@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接口(interface),如果你不能使用继承

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);
    }
}

关于android - Dagger2 转换为 android.dagger,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51399464/

相关文章:

android - 不保持 Activity 时清除 Intent

java - 如何在android studio中成对保存问题和答案?

android - 如何在 Fragment 中调用 OnActivityResult 以及它是如何工作的?

android - 如何在自定义 View 或其他 android 类中使用 AndroidInjection 类?

c# - 安卓 Xamarin C# : app runs in emulator but in actual device gets error: [INSTALL_PARSE_FAILED_BAD_MANIFEST]

android - 如何重新初始化 Hilt dagger 中的 Singleton 组件?

android - Dagger 2.10+ : Inject dependency with activity context in Activities and Fragments

android - 我应该在 BindAdapter 类中使用 inject 吗?

android - 在 Dagger2 中仅包含一次 ActivityScope 模块

dagger-2 - 如何使用AndroidInjector.Factory?