2016-04-27 2 views
1

Скажем, у нас есть класс Counter:В Dagger2, какова цель аннотации @Singleton?

public class Counter { 
    private int count; 

    public Counter() { 
     count = 0; 
    } 

    public int getCount() { 
     return count; 
    } 

    public void count() { 
     count++; 
    } 
} 

И ApplicationModule, что обеспечивает счетчик:

@Module 
public class ApplicationModule { 
    private Context context; 
    private Counter counter; 

    public ApplicationModule(Context context) { 
     this.context = context; 
     counter = new Counter(); 
    } 

    @Provides @Singleton 
    public Counter provideCounter() { 
     return counter; 
    } 
} 

Добавляя @Singleton аннотацию к методу provideCounter(), вы указав, что только один объект счетчик предоставляться?

В том случае, если мы предлагаем два Counter объекты:

@Module 
public class ApplicationModule { 
    private Context context; 
    private Counter numberOfTimesButtonAWasPressed; 
    private Counter numberOfTimesButtonBWasPressed; 

    public ApplicationModule(Context context) { 
     this.context = context; 
     numberOfTimesButtonAWasPressed = new Counter(); 
     numberOfTimesButtonBWasPressed = new Counter(); 
    } 

    @Provides @Named("buttonACounter") 
    public Counter provideButtonACounter() { 
     return numberOfTimesButtonAWasPressed; 
    } 

    @Provides @Named("buttonBCounter") 
    public Counter provideButtonBCounter() { 
     return numberOfTimesButtonBWasPressed; 
    } 
} 

Будет ли @Singleton аннотацию быть незаконным?

ответ

2

@Singleton будет убедиться, что есть только один в своем роде в компоненте.

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

@Provides @Named("buttonBCounter") 
public Counter provideButtonBCounter() { 
    return numberOfTimesButtonBWasPressed; 
} 

Это говорит о том, когда мне нужно Counter имени buttonBCounter вызов этого метода, но всегда одинаково objct будут возвращены из-за вашего модулей конструктора:

// don't do this. 
public ApplicationModule(Context context) { 
    numberOfTimesButtonAWasPressed = new Counter(); 
    numberOfTimesButtonBWasPressed = new Counter(); 
} 

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

// do it right 
@Singleton @Provides @Named("buttonBCounter") 
public Counter provideButtonBCounter() { 
    return new Counter(); 
} 

Это будет иметь тот же эффект, что и выше код, хотя метод будет вызываться только один раз , то крестик будет обрабатывать надлежащее кэширование объектов.

Использование кинжала, вероятно, это хорошая идея, чтобы позволить кинжалу позаботиться о создании объекта.

Затем вы можете даже пойти дальше и сделать что-то вроде ...

// if you have an @Inject annotated constructor 
@Singleton @Provides @Named("buttonBCounter") 
public Counter provideButtonBCounter(Counter counter) { 
    return counter; 
} 

... который позволит вам в полной мере использовать инъекции конструктора. Нет необходимости обновлять параметры, если они меняются.

Также, если есть сомнения, просто добавьте инструкции регистрации и/или приложите отладчик. В этом нет много волшебства, продолжайте и попробуйте!

+0

Большое вам спасибо! Это прояснило все! – AgileNinja

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