2016-11-08 68 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

嘿,谢谢,这也可以解决我的问题。 –