gpt4 book ai didi

android - 使用 Dagger 2 在库模块中注入(inject)应用程序上下文

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:49:06 24 4
gpt4 key购买 nike

我正在构建一个具有某些功能的应用程序:ContentProvider、SyncAdapter、作业服务和相关的持久性逻辑。在这些之上是带有 UI 的 Activity 。我试图将所有上述功能放在一个单独的库模块中,因为理论上它们的逻辑是独立的,并且可以被任何应用程序重用。

现在是 Dagger2。我的库的依赖关系图的第一个节点(主组件)确实需要提供上下文,并且这个上下文必须从应用程序中注入(inject),因为库范围具有与应用程序相同的生命周期。显然,为了自包含,我的库不应该直接使用我的 Application 类。

这些是我想到的可能性:

  • 在我的应用程序中构建库的主要组件,并按照建议将其存储在全局静态类/枚举中 here但我担心使用这样的静态引用可能是一种反模式。
  • 在库中打包一个构建库范围组件的应用程序类,将应用程序上下文转换到库中的此类以使用该组件,然后在主应用程序上扩展此应用程序类。这行得通,但如果有多个库,它就不再可行了。
  • 使用工厂模式:在提供工厂的库组件中放置提供方法,工厂又被赋予本地可用的上下文作为参数。 (如解释 here )。这似乎是可行的,尽管它增加了额外的复杂性。
  • 最后但并非最不重要的一点是,放弃对组件进行模块化的尝试,因为依赖于应用程序上下文会破坏模块化的概念。

正确的做法是什么?

最佳答案

Dagger 2 for Android来救援。它提供了 AndroidInjector 的概念,它是一个 Component,可用于以静态方式注入(inject)实例,而无需知道依赖项提供程序。此外,使用开箱即用的 Dagger- 前缀类,注入(inject)的依赖项看起来像是从哪里冒出来的。太棒了。

您所要做的就是在库中声明一个安装在应用程序组件中的顶级模块。此 Module 将提供库所需的所有依赖项和 SubComponent,它们将自动继承您在依赖关系图,随时可以注入(inject)您库中的任何位置,以及您通过主应用程序组件提供的每个依赖关系。

这是一个简短的例子(用 Kotlin 编写):

@Component(modules = [
AndroidSupportInjectionModule::class,
AppModule::class,
LibraryModule::class //plug-in the library to the dependency graph
])
@Singleton
interface AppComponent : AndroidInjector<App> {

@Component.Builder
abstract class Builder : AndroidInjector.Builder<App>() {

@BindsInstance
abstract fun appContext(@AppContext context: Context)

override fun seedInstance(instance: App) {
appContext(instance)
}
}
}

编辑:扩展示例

Application 子类的示例:

// DaggerApplication provides out-of-the-box support to all the AndroidInjectors.
// See the class' code to understand the magic.
public class App extends DaggerApplication {

@Override
protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
// We only provide its own Injector, the Application Injector,
// that is the previous AppComponent
return DaggerAppComponent.builder().create(this);
}

在你的 Android 库中:

@Module
public abstract class LibraryModule {

@ContributesAndroidInjector
public abstract LibraryActivity contributeLibraryActivityInjector();

}

public class LibraryActivity extends DaggerAppCompatActivity {

@Inject
@AppContext
Context appContext;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceSate);
// here you automagically have your injected application context!
ExternalSingleton.getInstance(appContext)
}
}

关于android - 使用 Dagger 2 在库模块中注入(inject)应用程序上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47929260/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com