Search
Write a publication
Pull to refresh
1
0
Артем Гильмудинов @Guliash

Пользователь

Send message

Спасибо за статью.

KSP у нас не давал больших профитов по сравнению с kapt (Yatagan KSP vs Yatagan kapt, когда я делал замеры).

А есть идеи почему так вышло? Интуитивно KSP должен быть быстрее, так как не надо генерить стабы. Или у вас остались в модуле подключенные kapt зависимости?

Пример
@Subcomponent
public interface MainActivitySubcomponent extends AndroidInjector<MainActivity> {

    @Subcomponent.Builder
    abstract class Builder extends AndroidInjector.Builder<MainActivity> {

        @Override
        public void seedInstance(MainActivity instance) {
            someInteger(instance.getInt());
            someString(instance.getString());
        }

        @BindsInstance
        public abstract Builder someInteger(Integer integer);

        @BindsInstance
        public abstract Builder someString(String string);
    }

}


Таким образом в граф добавятся Integer и String из активити и их можно будет инджектить.
«Но если у нас в активити инджектится DispatchingAndroidInjector (для внедрения фрагментов), то ссылка на сабкомпонент активити замкнется через билдер сабкомпонента фрагмента (так как он является inner классом).»
Замкнется через провайдер билдера сабкомпонента фрагмента — напутал.
«Если заглянуть в код DispatchingAndroidInjector#maybeInject, то видно что там создается инстанс билдера». Создается инстанс сабкомпонента, а не билдера — напутал.
Большое спасибо за статью!

Хотел бы кое-что добавить:

1) AndroidInjectionModule нужен для пустых мап. Пустые мапы могут возникнуть когда мы не вставляем никаких сабкомпонентов Activtiy в компонент Application'a, но при этом инджектим в Application инстанс DispatchingAndroidInjector. Если же у нас есть хотя бы один IntoMap то все будет ok. Цитата из документации «You do not have to use @Multibinds for sets or maps that have at least one @IntoSet, @ElementsIntoSet, or @IntoMap binding, but you do have to declare them if they may be empty.».

2) «К примеру активити сабкомпонент создается в момент вызова AndroidInjection.inject() и живет до тех пор пока активити не уничтожена.». Казалось бы это не совсем правда? Если заглянуть в код DispatchingAndroidInjector#maybeInject, то видно что там создается инстанс билдера, а сам он никуда не сохраняется. Но если у нас в активити инджектится DispatchingAndroidInjector (для внедрения фрагментов), то ссылка на сабкомпонент активити замкнется через билдер сабкомпонента фрагмента (так как он является inner классом). В итоге получается что сабкомпоненты самых глубоких сущностей умирают сразу после инджекта.

3) Касательно передачи динамических параметров. 1-й вариант плох тем, что требует контракта, что мы не используем userId, пока не вызван setUserId. 2-й вариант плох тем, что вьюха управляет презентером. 3-й способ наиболее чист, но как верно подмечено, слегка громоздок.
Добавлю еще 2 способа, которые нашел в issues даггера.
a) Инстанс активити или фрагмента, добавляется в граф после вызова AndroidInjection.inject(this), и поэтому все необходимые аргументы можно достать оттуда (то есть активити можно передавать как аргумент в Provides методы модуля и доставать оттуда что нужно).
b) Мы можем добавить BindsInstance методы в билдер, отнаследованный от AndroidInjector.Factory. Далее переопределяем метод seedInstance у билдера, и вызываем все методы BindsInstance, при этом достаем параметры из активити/фрагмента переданного аргументом в seedInstance. Вообще использование BindsInstance более предпочтительно чем конструкторы модуля. Из доков «Binding an instance is equivalent to passing an instance to a module constructor and providing that instance, but is often more efficient. When possible, binding object instances should be preferred to using module instances.»
Я как понял абстрактный модуль нельзя использовать в plus (ибо нужна реализация). Зато заработало если включить абс. модуль в неабстрактный модуль (includes в аннотации).
Спасибо за статью.
Возник вопрос с Binds. Может ли сабкомпонент иметь абстрактный модуль в качестве зависимости? Если да, то как создать такой модуль?

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Registered
Activity