Dagger 2 Activity context / ApplicationContext模块

时间:2015-08-08 20:03:14

标签: dagger-2

我正在与匕首2斗争,以便了解我如何根据自己的需要传递上下文。 - 首先我有一个ApplicationModule注释@Singleton,因为它提供高级对象,如webservice对象,模型......,通常这些对象传递给ApplicationContext(因为y需要在整个应用程序生命周期中存活)

@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
    

    @Module 公共类ActivityModule {     私人最终活动活动;

    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 qulifier我会收到错误
  • 以前的视图由另一个模块生成,它依赖于ActivityModule但仍然获取ApplicationContext

关键是我肯定错过了一些东西......但我无法弄清楚是什么,也许我对使用范围感到误解

2 个答案:

答案 0 :(得分:4)

你可以使用这样的限定符。在两个单独的文件中定义以下内容:

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

提供活动上下文。这只是一个例子。

答案 1 :(得分:0)

如果您想从模块中提供相同类型的多个对象,则需要

@Named

至于你的第二个问题,关于传递正确的Activity上下文,你需要在 ActivityComponent 中使用它:

Activity activity();