【问题标题】:Dagger 2 Activity context/ApplicationContext modulesDagger 2 Activity 上下文/ApplicationContext 模块
【发布时间】: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() 注释的原因。

标签: dagger-2


【解决方案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);
        }
    

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

    【讨论】:

      猜你喜欢
      • 2018-11-12
      • 1970-01-01
      • 2017-03-22
      • 1970-01-01
      • 2018-04-09
      • 2018-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多