Comments 30
Сэкономила и ещё сэкономит кучу времени в поисках нужной информации и её осмысления.
Спасибо за хорошую статью. Подобного материала действительно мало, и собирать его приходится с многих источников.
У меня вопрос по тестированию. Кроме подхода Артема Зиннатулина, есть еще библиотека от Фаббио Коллини — DaggerMock. Приходилось ли Вам смотреть ее раньше? И если да, то чем не подошла?
Возник вопрос с Binds. Может ли сабкомпонент иметь абстрактный модуль в качестве зависимости? Если да, то как создать такой модуль?
FirstModule, а не HelperModule. Абстрактный модуль подключается точно также, как и обычный. Никаких отличий.
Попробую разные варианты и добавлю к статье.
Спасибо большое!
Вы и заметить не успеете, как обрастете классами и разными зависимостями.
Для домашнего проекта, конечно же, это все можно опустить.
Смущают вызовы MyApplication.getInstance().getFirstComponent().inject(this) — не ясно, куда вставлять эти вызовы в обычном приложении.
Вызовы эти вставлять в зависимости от вашей логики. Обычно в onCreate() Активити или фрагмента.
Несмотря на то, что Даггер второй писался для андроида, явно андроидовские зависимости Даггер нигде не тянет. Вся его андроидо-ориентированость — это неиспользование рефлексии и меньшее потребление ресурсов, правда за счет большего оверхеда в написании кода. Так что теоретически должен работать и вне его.
Будет работать, юзаю для бекенд приложений.
MyApplication.getInstance().getFirstComponent().inject(this)
— не ясно, куда вставлять эти вызовы в обычном приложении.
Зависит от того, как построено ваше приложение, если на каком-то фреймворке типа Spring/Jersey — там так же есть объекты приложения, можно завязаться на них, в простейшем случае с public static void main()
вы можете просто таскать component
сквозь все функции и обойтись вообще без классов!
Google изначально делали Dagger2 для своих бекендов.
Экономия и минус лишние вызовы. Собственно у нас выигрыш по производительности. Также пишут, что вызов статического метода на 15-20% быстрее вызова аналогичного нестатического метода. Если я ошибаюсь, iamironz поправит меня. Уж он то точно знает, а если нужно, и замерит.
Данный тезис правдив скорее до Android API 19. На данный момент invokestatic почти ничем не отличается от invokevirtual т.к. в ART он девиртуализируется достаточно эффективно.
Вот, скажем, провайдим мы в AppModule сингельтон ApiClient, который далее много где планируется использовать.
И в итоге чтобы его заюзать нужно везде дергать что-то вроде?:
App.get(context).getComponent().inject() или App.get(context).getComponent().getApiClient()
т.е везде тянется зависимость от Application
чем это отличается от того, чтобы просто дергать App.get(context).getApiСlient() без использование Dagger?
Т.е весь код в итоге все равно будет обвязан App.getComponent, это смущает
Возмодно я что пропустил, но пока не понял можно ли избавиться от привязки к Application везде где нужно сделать inject
Может эта статья прояснит больше — https://habrahabr.ru/company/tcsbank/blog/312196/
То? Или вы несколько про другое?
Есть ParentClass1 и ParentClass2 которые реализуют интерфейс MyCallback
Есть ChildClass
конструктор класса ChildClass выглядит вот так
public ChildClass(MyCallback callback) {...}
т.е. Child имеет связь с Parent через интерфейс
Я бы хотел в классе ParentClass1 и ParentClass2 указать
Inject
ChildClass childClass;
Нам нужно к презентеру подключить зависимый презентер, а этот зависимый презентер хочет некий интерфейс от родителя.
Можно конечно поключать интерфейс позже к зависимому презентеру, но вот интересно умеет ли даггер что-то подобное.
Презентер и зависимый презентер. Почему так? Почему вы решили так разделить? Вообще зачем презентерам знать друг о друге? Их можно связать через локальный «EventBus».
Конечно, никто не запрещает вам подменять код через flavors. Но dagger — это не только лишь возможность подмены кода.
Иначе вам придется вручную создавать и прокидывать зависимости.
Поясните пожалуйста.
Очевидно, что вот это тоже пишется не автоматически:
@Inject
@Named("SingleThread")
Executor singleExecutor;
/*далее в onCreate*/
Executor singleExecutor = singleExecutorProvider.get();
При этом lazy load вообще выглядит громоздким. Я смутно могу себе представить, зачем нам понадобился ThreadPoolExecutor в activity, но допустим. Без даггера мы могли бы например написать просто:
Executor singleExecutor = ThreadPoolFactory.getSigleExecutor();//одна строчка!!!
А вы читали первые две статьи? Там я в принципе раскрываю, зачем нужен Даггер и как его готовить.
Готовить его для начинающего сложно. А польза сомнительна. В том числе и с точки зрения поддержки кода и понимания логики работы приложения в целом.
RxJava ты могуч, ты гоняешь стаи туч… Скажите на ваш взгляд если нужно что то вроде Supplier только для поздней инициализации, но не хочется тянуть по тем же причинам Guava и если сделать это как:
Observable<String> lazyString = Observable.just("Just do it");
// Usage
lazyString.toBlocking().first();
Насколько нарушается кошерность и можно ли это сделать по другому, без ретро ламбда?
JFYI Observable.just("Just do it")
не lazy, вы вычисляете аргумент во время вызова just
, а не во время подписки. Observable.fromCallable
— lazy, defer()
тоже и тп.
В вашем случае, что нибудь вроде Callable<String>
подойдет, если не нужно кеширование результата. Если нужно кеширование, то это классик строк на 10, который будет вычислять значение если его еще нет в кеше, и отдавать из кеша если уже есть. Если вы используете Kotlin, в его stdlib есть lazy
.
Dagger 2. Часть третья. Новые грани возможного