2016-09-22 149 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