使用Dagger将android.content.Context注入构造函数

时间:2018-07-11 13:18:19

标签: android dagger-2

我正在创建一个Android Java类,我想在其中了解设备的国家和语言。

我正在从android.content.Context获取该信息。

我试图像这样将Context注入类的构造函数中:

@Inject
public MyClass(Context context) {
    this.context = context;
}

但是,我遇到此错误:

Error:(26, 22) error: android.content.Context cannot be provided without an @Provides-annotated method.
android.content.Context is injected at

那我需要在哪里添加这个@Provider

否则,如何将Context对象注入我的班级?

1 个答案:

答案 0 :(得分:1)

简单地说,您需要将那个into a Module that you create放在应用程序的Component批注中。但是,有一些细微差别:

如何将您的Application实例放入图中?在大多数情况下,您会在指定的Application子类中创建顶级Dagger组件(用@Singleton注释)在清单中,然后在组件构建器上使用@BindsInstance方法来设置特定应用程序的实例。然后,在Application.onCreate上,您可以创建顶级Dagger组件并将其设置在Application字段上。这将使您的组件具有与应用程序相同的生命周期,从而使@Singleton范围的绑定像VM单例一样工作。从技术上讲,您可以直接将Context传递到@BindsInstance方法中,但是您可能需要应用程序子类YourApplication来代替;您可以在不进行强制转换的情况下从YourApplication到达应用程序或Context,但是不能以相同的方式从Context到达应用程序或YourApplication。

如果您使用dagger.androidDaggerApplication,而该Builder superclass called AndroidInjector使用pass your Android-created object into the graph,则此@BindsInstance代码是自动的,因此您始终可以getApplication() vs. getApplicationContext()

如何从应用程序到应用程序以及从应用程序到上下文?

Dagger不会自动绑定超类,因此,如果您为YourApplication使用@BindsInstance方法,则Dagger不一定能够推断Application或Context的绑定。因此,在一个抽象模块中想要这样的方法是很常见的:

@Binds abstract Application bindApplication(YourApplication yourApplication);

@Binds abstract /* @ApplicationContext */ Context bindApplicationContext(
    Application application);

请注意,即使getApplication()getApplicationContext()在大多数现代Android实现中也能返回相同的内容。另请参阅以下SO问题:different Contexts can do different things

您想要哪个上下文?尽管Context是通用界面,但在Android create Qualifier annotations中。如果您像dagger.android一样使用Subcomponents,您将在Activity的组件中继承Application绑定,这通常很好,但也可能意味着Context绑定必然是您在Application级别上绑定的对象-您不会得到在本地覆盖它。因此,您可能想像@ActivityContext@ApplicationContext那样component dependencies instead of subcomponents来区分它们,从而为您的类清楚地记录是可以期望应用程序上下文还是活动上下文。

如果使用{{3}},则不会自动继承应用程序中的所有绑定,而不会自动继承组件上列出的所有绑定(或列出为依赖项的任何接口)。有了这种灵活性,您可以选择始终将最本地的上下文直接注入,然后在特别需要应用程序上下文时显式调用Context.getApplicationContext()。但是,此优点可能不值得在Component上列出所有继承的绑定,并且还可能引入一些细微的错误:与在Activity的Component中注入相同的对象相比,您可能在应用程序的Component中注入一个对象的上下文不同。导致运行时错误,因为上下文无法执行相同的操作。如果您沿着这条路线走,请谨慎操作。