【问题标题】:Dagger 2, Library modules and @SingletonDagger 2,库模块和@Singleton
【发布时间】:2017-03-22 06:40:10
【问题描述】:

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

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

我不能做的是提供一个实例作为单例。

项目结构如下:

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

同样,我想要实现的只是在我的主应用程序项目中注入库项目提供的一些管理器的单例范围实例

【问题讨论】:

  • 我猜你需要从库中公开modules,而不是components
  • @EpicPandaForce 抱歉,我对 Dagger 的经验很少:我没有创建组件,而是创建了模块,我在其中提供了我的经理实例;如果我不放置任何作用域,它再次工作正常,但如果我尝试使用 @Singleton 作用域,就像我在 MainComponent 中放置的一样,我会收到编译错误Error:Execution failed for task ':app:compileDebugJavaWithJavac'. > java.lang.NoClassDefFoundError: dagger/internal/ScopedProvider
  • 一些消息:模型建议有效,我在 App 模块中有不同版本的 Dagger,这导致了 NoClassDefFoundError。我会用工作代码写一个答案。

标签: android dagger-2


【解决方案1】:

正如@EpicPandaForce 所建议的,使用 Dagger 模块而不是组件解决了我的问题

接下来,我必须进行必要的更改。

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

@Module
public class LibraryModule {

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

不仅仅是在 App 组件中指定那些模块,代替组件的依赖项:

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

    void inject(MainActivity target);
}

就是这样,在这段代码中,使用 @Singleton 范围注释的 Manager 类只被正确实例化一次。

【讨论】:

  • 如果我们实现独立的库模块,则无法通过这种方法使用像 @AppScope 这样的自定义范围。
【解决方案2】:

尝试将库组件统一在单个组件下(例如:AllLibrariesComponent),然后让您的 MainComponent 仅依赖 AllLibrariesComponent。

图书馆 1:

@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 ***");
    }
}

图书馆 2:

@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();

【讨论】:

  • 嘿,谢谢,这也可以解决我的问题。
  • 如果需要,如何为LibraryComponent的MyManager类提供上下文?
猜你喜欢
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多