2016-11-08 62 views
9

我試圖在具有幾款Android庫模塊 Android項目中的使用匕首2,我希望能夠提供單範圍的類的實例從這些模塊。匕首2,庫模塊和@Singleton

目前我能夠定義庫模塊內的組件,並在主應用程序模塊中注入實例。

我無法做的是提供一個實例作爲單身人士。

項目結構如下:

Project 
├── app 
├── library1 
· 
· 
· 
└── libraryN 

在我定義的組件這樣的庫:

@Component 
public interface LibraryComponent { 

    // Provide instances of MyManager to MainComponent: 
    MyManager getMyManager(); 
} 

而且MyManager看起來是這樣的:

public class MyManager { 

    private static final String TAG = "MyManager"; 

    @Inject 
    public MyManager() { 
     Log.d(TAG, "Creating MyManager"); 
    } 
} 

在主應用程序中,我以這種方式定義我的組件:

@ApplicationScope 
@Component(dependencies = {LibraryComponent.class, Library2Component.class}) 
public interface MainComponent { 

    void inject(MainActivity target); 
} 

這是應用程序類:

public class App extends Application { 
    private MainComponent component; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 

     component = DaggerMainComponent.builder() 
       .libraryComponent(DaggerLibraryComponent.create()) 
       .library2Component(DaggerLibrary2Component.create()) 
       .build(); 
    } 

    public MainComponent getComponent() { 
     return component; 
    } 
} 

如果我添加一個範圍,只有一個庫組件,那麼我就能夠提供經理作爲一個單身。但是,如果我嘗試做同樣多一個圖書館,我發現了錯誤:

@com.codeblast.dagger2lib.ApplicationScope com.codeblast.dagger2lib.MainComponent depends on more than one scoped component: 
@Component(dependencies = {LibraryComponent.class, Library2Component.class}) 
^ 
     @com.codeblast.library.LibraryScope com.codeblast.library.LibraryComponent 
     @com.codeblast.library2.Library2Scope com.codeblast.library2.Library2Component 

同樣,我想實現的是在我的主要應用程序項目單只是爲了注入作用域的一些實例圖書館提供的經理項目

+3

我想,你需要從庫中公開'modules',而不是'components'。 – EpicPandaForce

+0

@EpicPandaForce很抱歉,我對Dagger沒有多少經驗:我沒有創建模塊,而是提供了我的管理器實例;再次它工作正常,如果我不放任何範圍,但如果我嘗試使用@Singleton範圍,我放在MainComponent,我得到編譯錯誤'錯誤:執行失敗的任務':應用程序: compileDebugJavaWithJavac」。 > java.lang.NoClassDefFoundError:dagger/internal/ScopedProvider' –

+1

某些消息:模型建議奏效,我在應用程序模塊中使用了不同版本的Dagger,導致了NoClassDefFoundError。我會用工作代碼寫一個答案。 –

回答

9

如所建議的通過@EpicPandaForce,使用Dagger模塊而不是組件解決了我的問題

以下是我必須做出的必要修改。

第一個被刪除庫組件創建庫模塊:

@Module 
public class LibraryModule { 

    @Singleton 
    @Provides 
    MyManager provideMyManager(MyUtility myUtility) { 
     return new MyManager(myUtility); 
    } 
} 

不僅僅是指定的應用程序組件的模塊,將組件的依賴關係:

@Singleton 
@Component(modules = {LibraryModule.class, Library2Module.class}) 
public interface MainComponent { 

    void inject(MainActivity target); 
} 

而這它使用@Singleton作用域註釋的Manager類,只能正確實例化一次。

1

嘗試將單個組件下的庫組件統一起來(例如:AllLibrariesComponent),然後讓MainComponent作爲依賴項僅使用AllLibrariesComponent。

分享幫助:

@Component 
@Singleton 
public interface LibraryComponent { 

    // Provide instances of MyManager to MainComponent: 
    MyManager getMyManager(); 

} 

@Singleton 
public class MyManager { 

    private static final String TAG = "MyManager"; 

    @Inject 
    public MyManager() { 
     Log.d(TAG, "*** Creating MyManager 1 ***"); 
    } 
} 

Library2:

@Singleton 
@Component 
public interface Library2Component { 

    // Provide instances of MyManager to MainComponent: 
    MyManager2 getManager2(); 

} 

@Singleton 
public class MyManager2 { 

    private static final String TAG = "MyManager"; 

    @Inject 
    public MyManager2() { 
     Log.d(TAG, "*** Creating MyManager 2 *** "); 
    } 
} 

應用程式:

@Singleton 
@Component 
public interface AllLibrariesComponent extends Library2Component, LibraryComponent{ 
} 

@PerApplication 
@Component(dependencies = AllLibrariesComponent.class) 
public interface MainComponent { 

    void inject(MainActivity activity); 

} 

// .... 
// and the instantication in your application class: 
mainComponent = DaggerMainComponent.builder() 
       .allLibrariesComponent(DaggerAllLibrariesComponent.create())     
       .build(); 
+1

嘿,謝謝,這也可以解決我的問題。 –