2015-08-08 5 views
6

Я борется с кинжалом 2, чтобы понять, как я могу передать контекст или другое в соответствии с моими потребностями. - Сначала у меня есть аннотированный @Singleton ApplicationModule, поскольку он предоставляет высокоуровневые объекты, такие как объект webservice, модель ..., как правило, эти объекты передаются ApplicationContext (так как y нужно жить в течение всего срока службы)Кинжал 2 Контекст активности/Модули 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(); 
    } 
... 
  • во-вторых у меня есть активность Scope componenet с использованием I обеспечивают текущую деятельность и различные точки зрения, которые нуждаются в контексте.

    @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

Ну Дело в том, что я, конечно, чего-то не вижу ... но я не могу понять, что, может быть, я не понимаю, как использовать Scopes

+2

Учитывая, что у вас есть два 'Context', которые почти одинаковы, вам нужно указать' @Named ("application") 'и' @Named ("activity") 'на них. – EpicPandaForce

+0

Хотя на самом деле вы можете просто ** не добавлять ** контекстный контекст() 'к своему компоненту, только к модулю, и он также будет работать! – EpicPandaForce

+0

Поскольку Кинжал выполняет инъекцию на основе типа, имеющего два метода, которые предоставляют класс Context, может вызвать ошибку, поэтому хорошие люди включили аннотацию @Named(). – fakataha

ответ

0

@Named - это требование, если вы хотите предоставить несколько объектов одного типа из вашего модуля.

Что касается вашего второго вопроса, в отношении прохождения правильного контекста активности, вы должны иметь это в ActivityComponent:

Activity activity(); 
1

вы можете использовать классификаторы, как это. в двух отдельных файлах определить следующее:

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

обеспечить контекст деятельности. это просто пример.

Смежные вопросы