2016-09-22 119 views
0

我有两个singletone类,我想将它们注入到Fragments,Activites等中,但我也要将它们注入彼此。 在这一点上,我总是得到SO错误。匕首2周期注射

public class AdverticumChecker implements IAdverticumChecker { 

    @Inject BannerManager bannerManager; 

    public AdverticumChecker(Context context) { 
     IndexApplication.getApplication().getAppComponent().inject(this); 
    } 
} 

public class BannerManager { 
    @Inject IAdverticumChecker adverticumChecker; 

    public BannerManager(){ 
     IndexApplication.getApplication().getAppComponent().inject(this); 
    } 
} 

这些模块

@Module 
public class BannerManagerModule { 

     @Singleton 
     @Provides 
     BannerManager provideBannerManager(){ 
      return new BannerManager(); 
     } 
    } 

@Module 
public class AdverticumCheckerModule { 
    private Context context; 

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

    @Singleton 
    @Provides 
    IAdverticumChecker provideAdverticumChecker(){ 
     return new AdverticumChecker(context); 
    } 
} 

我在应用程序类建立图一次。 这里是错误:第一

FATAL EXCEPTION: main java.lang.StackOverflowError at com.aff.index.adverticum.AdverticumChecker_MembersInjector.injectMembers(AdverticumChecker_MembersInjector.java:38) at com.aff.index.adverticum.AdverticumChecker_MembersInjector.injectMembers(AdverticumChecker_MembersInjector.java:8) at com.aff.index.dagger.DaggerAppComponent.inject(DaggerAppComponent.java:679) at com.aff.index.adverticum.AdverticumChecker.(AdverticumChecker.java:50) at com.aff.index.dagger.AdverticumCheckerModule.provideAdverticumChecker(AdverticumCheckerModule.java:30) at com.aff.index.dagger.AdverticumCheckerModule_ProvideAdverticumCheckerFactory.get(AdverticumCheckerModule_ProvideAdverticumCheckerFactory.java:24) at com.aff.index.dagger.AdverticumCheckerModule_ProvideAdverticumCheckerFactory.get(AdverticumCheckerModule_ProvideAdverticumCheckerFactory.java:8) at dagger.internal.DoubleCheck.get(DoubleCheck.java:46) at com.aff.index.adverticum.BannerManager_MembersInjector.injectMembers(BannerManager_MembersInjector.java:67) at com.aff.index.adverticum.BannerManager_MembersInjector.injectMembers(BannerManager_MembersInjector.java:11) at com.aff.index.dagger.DaggerAppComponent.inject(DaggerAppComponent.java:704) at com.aff.index.adverticum.BannerManager.(BannerManager.java:89) at com.aff.index.dagger.BannerManagerModule.provideBannerManager(BannerManagerModule.java:21) at com.aff.index.dagger.BannerManagerModule_ProvideBannerManagerFactory.get(BannerManagerModule_ProvideBannerManagerFactory.java:24) at com.aff.index.dagger.BannerManagerModule_ProvideBannerManagerFactory.get(BannerManagerModule_ProvideBannerManagerFactory.java:8) at dagger.internal.DoubleCheck.get(DoubleCheck.java:46) at com.aff.index.adverticum.AdverticumChecker_MembersInjector.injectMembers(AdverticumChecker_MembersInjector.java:39) at com.aff.index.adverticum.AdverticumChecker_MembersInjector.injectMembers(AdverticumChecker_MembersInjector.java:8) at com.aff.index.dagger.DaggerAppComponent.inject(DaggerAppComponent.java:679)

回答

0

第一件事,这...

@Singleton 
@Provides 
IAdverticumChecker provideAdverticumChecker(){ 
    return new AdverticumChecker(context); 
} 
... 
public AdverticumChecker(Context context) { 
    IndexApplication.getApplication().getAppComponent().inject(this); 
} 

规避什么DI代表,基本上依赖注入,而不是在构造函数中注入他们让一些静态访问神奇 - 这种方式AdvertiumChecker几乎不可能测试!列出你所有的依赖构造函数的参数,而不是做这样的:

@Singleton 
@Provides 
IAdverticumChecker provideAdverticumChecker(BannerManager bannerManager){ 
    return new AdverticumChecker(bannerManager); 
} 
... 
private BannerManager mBannerManager; 
public AdverticumChecker(BannerManager bannerManager) { 
    mBannerManager = bannerManager; 
} 

匕首会自动填补国内空白,为你在这里,构建一个适当的图表。其次,如果BannerManager的构建依赖于IAdvertiumChecker的实例,那么您显然会有一个循环依赖关系,Dagger会错误地回答这个问题。通常情况下,这听起来像不好的设计,但有时它不能以不同的方式执行,以防在运行时需要某些东西。

在这种情况下,与Lazy注射,即无论是

@Inject 
Lazy<BannerManager> mLazyBannerManager; 
... 
mLazyBannerManager.get().doSomething(); 

IAdvertiumChecker providerAdvertiumChecker(Lazy<BannerManager> lazyBannerManager) { 
    return new AdverticumChecker(lazyBannerManager); 
} 

希望这有助于工作。

+0

非常感谢,通过参数槽构造函数和使用懒惰注入在我看来,它的工作原理。但是现在我有点困惑。我该如何决定什么时候需要在构造器中传递参数以及何时使用@Inject来注入依赖关系? – user3057944

+0

如果你不用接口隐藏你的实现,你可以用'@Inject'来简单地注释一个类的构造函数,而Dagger2使用这个构造函数来创建这个类。在这样的构造函数中,您可以自己添加(并绑定)所有参数(即'@Inject public Foo(Bar bar,Baz baz);'),或者使用空的构造函数并使用@ @Inject注释所有可注入成员'。 –

+0

非常感谢,我现在可以继续提供帮助。无论如何,我现在还有一个问题。我在我的应用程序中使用了singletone类,并在这些cals中使用了同步方法。但是因为我让匕首创建单例,如果我的方法是sychnronized,他们会终止工作。但是,当我删除同步关键字,工作。如果我用匕首创建单例,我不能在单数类中使用同步方法吗? – user3057944