Dagger 2 Activity context/ApplicationContext模块

gro*_*apa 8 dagger-2

我正在努力与匕首2,以了解我如何根据我的需要传递一个或另一个上下文. - 首先我有一个ApplicationModule注释@Singleton,因为它提供了高级对象,如webservice对象,模型......,通常那些对象传递给ApplicationContext(因为y需要在整个Application生命周期中生存)

@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)
...
Run Code Online (Sandbox Code Playgroud)

实现看起来像那样

@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();
    }
...
Run Code Online (Sandbox Code Playgroud)
  • 其次我有一个活动范围组件,我提供当前活动和需要上下文的不同视图.

      @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
    
    Run Code Online (Sandbox Code Playgroud)

    @Module公共类ActivityModule {private final Activity 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;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    所以这是我的问题:

  • 我使用范围以获得比传递的更好的"粒度",我仍然得到applicationContext
  • 如果我删除@Named qulifier我会收到错误
  • 以前是由另一个模块生成的视图,它依赖于ActivityModule但仍然获得ApplicationContext

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

j2e*_*nue 5

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

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface ActivityContext {
}

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface ApplicationContext {
}
Run Code Online (Sandbox Code Playgroud)

然后在您的 ActivityModule 中执行以下操作:

@Provides
@ActivityScope
@ActivityContext
public Context context() {
    return activity;
}
Run Code Online (Sandbox Code Playgroud)

同样在你的 appmodule 中这样做:

 @Provides
    @Singleton
@ApplicationContext
    Context provideApplicationContext() {
        return app.getApplicationContext();
    }
Run Code Online (Sandbox Code Playgroud)

现在我们有一种方法可以根据限定符@ApplicationContext 和@ActivityContext来请求我们需要的任何类型的上下文

因此,例如在您的活动中,您可以这样做:

  @Inject @ApplicationContext
    Context c;
Run Code Online (Sandbox Code Playgroud)

这将注入应用程序上下文。

在一个模块中,你可以这样做,例如:

  @Provides
    @ActivityScope
    LoginPresenter provideLoginPresenter(@ActivityContext Context context) {
        return new LoginPresenter(context);
    }
Run Code Online (Sandbox Code Playgroud)

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


Igo*_*sky 0

@Named如果您想从模块中提供相同类型的多个对象,则这是一个要求。

至于你的第二个问题,关于传递正确的 Activity 上下文,你需要在ActivityComponent中包含以下内容:

Activity activity();
Run Code Online (Sandbox Code Playgroud)