Dagger 2,图书馆模块和@Singleton

Rob*_*rdi 13 android dagger-2

我正在尝试在具有多个Android库模块的Android项目中使用Dagger 2,并且我希望能够从这些模块提供单例范围的类实例.

目前,我能够在库模块中定义组件,并在主应用程序模块中注入实例.

我无法做的是提供一个单例实例.

项目结构如下:

Project
??? app
??? library1
·
·
·
??? libraryN
Run Code Online (Sandbox Code Playgroud)

在库中我用这种方式定义组件:

@Component
public interface LibraryComponent {

    // Provide instances of MyManager to MainComponent:
    MyManager getMyManager();
}
Run Code Online (Sandbox Code Playgroud)

而MyManager看起来像这样:

public class MyManager {

    private static final String TAG = "MyManager";

    @Inject
    public MyManager() {
        Log.d(TAG, "Creating MyManager");
    }
}
Run Code Online (Sandbox Code Playgroud)

在主App中,我以这种方式定义我的组件:

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

    void inject(MainActivity target);
}
Run Code Online (Sandbox Code Playgroud)

这是Application类:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我只将范围添加到一个库组件,那么我就可以将管理器作为单例提供.但是如果我尝试对另外一个库做同样的事情我会收到错误:

@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
Run Code Online (Sandbox Code Playgroud)

同样,我想要实现的只是在我的主应用程序项目中注入由Library项目提供的一些Managers的单例范围实例.

Rob*_*rdi 10

正如@EpicPandaForce所建议的,使用Dagger Modules而不是Components解决了我的问题.

接下来,我必须做出必要的改变.

第一个是删除库组件并创建库模块:

@Module
public class LibraryModule {

    @Singleton
    @Provides
    MyManager provideMyManager(MyUtility myUtility) {
        return new MyManager(myUtility);
    }
}
Run Code Online (Sandbox Code Playgroud)

不只是在App Component中指定那些模块,而不是Component的依赖项:

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

    void inject(MainActivity target);
}
Run Code Online (Sandbox Code Playgroud)

就是这样,使用@Singleton作用域注释的Manager类只需要一次正确实例化.