Подтвердить что ты не робот

Dagger 2 Custom Scope для каждого фрагмента (или Activity и т.д.)

Я рассмотрел пару разных статей, которые, как представляется, предлагают два разных способа выполнения пользовательского охвата в кинжале 2:

Из того, что я понимаю, кажется, что, как и в методе 2, должно быть хорошо иметь определенную область видимости, которая может использоваться для всех фрагментов (т.е. @PerFragment). На самом деле (пожалуйста, исправьте меня, если я ошибаюсь), похоже, что имя настраиваемой области не имеет значения, и это важно только там, где создается подкомпонент (т.е. В приложении, активности или фрагменте).

Есть ли какой-либо вариант использования для определения уникальной области для каждого фрагмента, например, в случае 1?

4b9b3361

Ответ 1

После прочтения ответа от @vaughandroid и Что определяет жизненный цикл компонента (граф объекта) в кинжале 2? Я думаю, что я хорошо понимаю пользовательские области ответьте на мой собственный вопрос.

Во-первых, вот пара правил при работе с компонентами, модулями и аннотациями в кинжале2.

  • A Компонент должен иметь аннотацию (одиночную) области видимости (например, @Singleton или @CustomScope).
  • A Модуль не имеет аннотации области.
  • Метод модуля может иметь (единую) область, которая соответствует ее Компонент или без области видимости, где:
    • Scoped: означает, что для каждого экземпляра компонента создается один экземпляр.
    • Недоступно: означает, что новый экземпляр создается с каждым вызовом inject() или провайдера
    • ПРИМЕЧАНИЕ. Dagger2 резервирует @Singleton только для корневого компонента (и его модулей). Подкомпоненты должны использовать настраиваемую область, но функциональность этой области точно такая же, как @Singleton.

Теперь, чтобы ответить на вопрос: я бы сказал, создайте новую именованную область для каждой концептуально различной области. Например, создайте аннотацию @PerActivity, @PerFragment или @PerView, которая указывает, где должен быть создан экземпляр компонента и, таким образом, указывает его время жизни.

Примечание: это компромисс между двумя крайностями. Рассмотрим случай корневой компоненты и n подкомпонентов, которые вам понадобятся:

  • не менее 2 аннотации (@Singleton и @SubSingleton) и
  • не более n + 1 аннотации (@Singleton, @SubSingleton1,... @SubSingletonN).

Пример:

Применение:

/** AppComponent.java **/ 
@Singleton
@Component( modules = AppModule.class )
public interface AppComponent{
    void inject(MainActivity mainActivity);
}

/** AppModule.java **/
@Module
public class AppModule{
    private App app;

    public AppModule(App app){
        this.app = app;
    }

    // For singleton objects, annotate with same scope as component, i.e. @Singleton
    @Provides @Singleton public App provideApp() { return app; }
    @Provides @Singleton public EventBus provideBus() { return EventBus.getDefault(); }
}

Фрагмент:

/** Fragment1Component.java **/
@PerFragment
@Component( modules = {Fragment1Module.class}, dependencies = {AppComponent.class} )
public interface Fragment1Component {
    void inject(Fragment1 fragment1);
}

/** Fragment1Module.java **/ 
@Module
public class Fragment1Module {
    // For singleton objects, annotate with same scope as component, i.e. @PerFragment
    @Provides @PerFragment public Fragment1Presenter providePresenter(){
        return new Fragment1Presenter();
    }
}

/** PerFragment.java **/ 
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface PerFragment {}

Ответ 2

Ваше понимание верное. Названные области позволяют вам сообщать намерения, но все они работают одинаково.

  • Для методов поставщиков с ограниченным охватом каждый экземпляр Component создаст 1 экземпляр предоставленного объекта.
  • Для методов поставщиков с нераспределенным доступом каждый экземпляр Component создаст новый экземпляр предоставленного объекта, когда ему нужно его ввести.

Тем не менее важно время жизни экземпляра Component. 2 разных экземпляра одного и того же компонента будут предоставлять разные экземпляры объектов, даже ограниченные.

Имена областей должны указывать время жизни предоставленного объекта (что соответствует экземпляру компонента), поэтому @PerFragment имеет для меня гораздо больше смысла.

Из краткого взгляда на учебник "MVP Presenters...", мне не ясно, в чем именно заключается намерение автора с отдельными областями. Поскольку имена являются просто выброшенными, я бы не стал читать слишком много.