Dagger 2 Activity 上下文/ApplicationContext 模块
Posted
技术标签:
【中文标题】Dagger 2 Activity 上下文/ApplicationContext 模块【英文标题】:Dagger 2 Activity context/ApplicationContext modules 【发布时间】:2015-11-01 02:19:26 【问题描述】:为了了解如何根据需要传递上下文或其他上下文,我正在努力使用 Dagger 2。 - 首先我有一个 ApplicationModule 注释 @Singleton 因为它提供了像 webservice 对象、模型......这样的高级对象,通常这些对象通过 ApplicationContext (因为你需要在整个应用程序生命周期中都存在)
@Singleton
@dagger.Component(modules =
AppModule.class
)
public interface AppComponent
void inject(MyApp application);
Model model();
Context context();<--- should provide the application Context for the Object above (model)
...
实现看起来像这样
@dagger.Module
public class AppModule
private final Application app;
public ApplModule(Application app)
this.app = app;
@Provides
@Singleton
Model provideModel(Bus bus)
return new Model(bus);
@Provides
@Singleton
Context provideApplicationContext()
return app.getApplicationContext();
...
其次,我有一个活动范围组件,我提供当前活动和需要上下文的不同视图。
@ActivityScope
@Component(
dependencies = AppComponent.class
, modules = ActivityModule.class
)
public interface ActivityComponent
void inject(MyActivity activity);
Context context(); <---should provide the activity's context
MyView homeView(); <----takes a Context as a contructor parameter
@模块 公共类 ActivityModule 私人最终Activity活动;
public ActivityModule(Activity activity)
this.activity = activity;
@Provides
@ActivityScope
public Activity activity()
return activity;
@Provides
@ActivityScope
@Named("viewcontext") <----- if I removed this I get an error from Dagger
public Context context()
return activity;
@Provides
@ActivityScope
MyView provideZeView(Bus bus, Model model) <---- previously receiving the ApplicationContext as a parameter
MyView v = new MyView(activity, bus, model); <---- must pass the activity otherwise passing the Context reveived is the ApplicationContext
return v;
所以这是我的问题:
我使用范围是为了对传递的内容有更好的“粒度”,但我仍然得到 applicationContext 如果我删除 @Named 限定符,我会收到错误消息 以前的视图是由另一个依赖于 ActivityModule 但仍获取 ApplicationContext 的模块生成的关键是我肯定遗漏了一些东西......但我不知道是什么,也许我误解了 Scopes 的使用
【问题讨论】:
考虑到您有两个几乎相同的Context
,您需要在它们上指定@Named("application")
和@Named("activity")
。
虽然实际上,您可以不添加 Context context()
到您的组件中,只添加到模块中,它也可以工作!
因为 Dagger 实现了基于类型的注入,该类型有两个提供 Context 类的方法可能会导致错误,这就是为什么好人包含 @Named() 注释的原因。
【参考方案1】:
如果您想从您的模块中提供多个相同类型的对象,则需要@Named
。
至于你的第二个问题,关于传递正确的 Activity 上下文,你需要在你的 ActivityComponent 中有这个:
Activity activity();
【讨论】:
【参考方案2】:您可以使用这样的限定符。在两个单独的文件中定义以下内容:
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface ActivityContext
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface ApplicationContext
然后在您的 ActivityModule 中执行以下操作:
@Provides
@ActivityScope
@ActivityContext
public Context context()
return activity;
同样在你的 appmodule 中这样做:
@Provides
@Singleton
@ApplicationContext
Context provideApplicationContext()
return app.getApplicationContext();
现在我们可以根据限定符 @ApplicationContext 和 @ActivityContext 询问我们需要的任何类型的上下文。
例如,在您的活动中,您可以这样做:
@Inject @ApplicationContext
Context c;
这将注入一个应用程序上下文。
在一个模块中你可以这样做:
@Provides
@ActivityScope
LoginPresenter provideLoginPresenter(@ActivityContext Context context)
return new LoginPresenter(context);
提供活动上下文。这只是一个例子。
【讨论】:
以上是关于Dagger 2 Activity 上下文/ApplicationContext 模块的主要内容,如果未能解决你的问题,请参考以下文章