【问题标题】:Dagger 2 single instance of MyClassDagger 2 MyClass 的单个实例
【发布时间】:2017-10-12 18:23:16
【问题描述】:

我正在尝试重构我的代码,因此我正在考虑使用 Dagger2 来解决我的问题。我创建了AppComponent 来存储我所有的Singletons

@AppScope
@Component(
        modules = {
                AppModule.class,
                // more here...
        }
)
public interface AppComponent {

    Context exposeContext();

    CmdComponent newCmdComponent(CmdModule module);

    // ... few injections here
}

我的AppModule

@Module
public class AppModule {

    private Context context;

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

    // ... provide appContext etc.

    @AppScope @Provides
    MyClass provideMyClass() {
        Log.i("DAGGER", "provideMyClass: ");
        return new MyClass();
    }

}

我将这个注入到我的Application 类中:

public class App extends Application {

    private static AppComponent component;

    @Override
    public void onCreate() {
        super.onCreate();
        component = DaggerAppComponent.builder()
                .appModule(new AppModule(app))
                .build();
    }

    public static AppComponent getAppComponent() {
        return component;
    }
}

然后我的子组件CmdComponent 与不同的@Scope

@CmdScope
@Subcomponent(
        modules = {
                CmdModule.class
        }
)
public interface CmdComponent {
    void inject(Cmd cmd);
}

现在我将依赖项注入到我的 Cmd 实例中,例如:

@Inject MyClass myClass;

public Cmd() {
    App.getAppComponent()
            .newCmdComponent(new CmdModule())
            .inject(this);
}

不幸地记录:Log.i("DAGGER", "provideMyClass: "); 和内部的登录 MyClass 构造函数多次显示...所以我每次都得到MyClass 的新实例。如何告诉 Dagger 每次都给我相同的实例(创建一次)?

【问题讨论】:

  • 您是否碰巧在运行 crashlytics、chuck 或其他有自己进程的库?我相信他们的过程会创建第二个Application,从而再次调用构造函数。您的代码本身看起来不错
  • 没有。如果我将日志放在 Application onCreate 方法中,它只会弹出一次
  • 我不知道为什么它会有所不同,但您是否尝试过组件依赖项(而不是使用Subcomponent)...在这里使用几乎相同的设置和应用程序范围对象只创建一次.
  • 嗯,我试过了,结果是一样的。之后,我决定创建子组件

标签: java android dependency-injection dagger-2


【解决方案1】:

好的。我解决了我的问题。解决方案很简单。我的 AppScope 创建错误。出于某种原因,我认为注释的工作方式类似于继承。

我的自定义注释是这样的:

@Singleton
@Retention(RetentionPolicy.RUNTIME)
public @interface AppScope {
}

Dagger 认为我的组件没有作用域。应该是这样的:

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

【讨论】:

    【解决方案2】:

    .newCmdComponent(new CmdModule()) 怎么样。你为什么这样做,每次都创建一个新模块?该组件已经附加了一个模块,您已经在创建组件时设置了它。

    【讨论】:

    • 他们已经使用AppScope作为他们的范围,不需要@Singleton
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-19
    相关资源
    最近更新 更多