Разделите компонент Dagger 2 между двумя разными вариантами

У меня есть два варианта: pro и free. В каждом из них у меня есть MainActivity, но я хочу, чтобы MainComponent и MainModule были одинаковыми для обоих, поэтому MainComponent и MainModule оба находятся в src/java/main, но я получаю сообщение об ошибке в своем MainComponent из-за отсутствия импорт MainActivity обоих вариантов. Здесь, позвольте мне прояснить:

Вот как выглядит MainComponent в src/java/main:

import com.xxx.myapp.di.modules.MainModule;
import com.xxx.myapp.free.MainActivity;
import com.xxx.myapp.presenters.MainPresenterImpl;

import javax.inject.Singleton;

import dagger.Component;


@Singleton
@Component(modules = {MainModule.class})
public interface MainComponent {
    void inject(MainActivity mainActivity);
    void inject(MainPresenterImpl mainPresenter);
}

В коде, показанном выше, он импортирует только MainActivity из бесплатной версии, поэтому выдает ошибку, когда я переключаюсь на профессиональную версию.


person Community    schedule 02.12.2015    source источник


Ответы (2)


При использовании ароматизаторов у вас не должно быть разных пакетов для разных компонентов.

Вместо com.xxx.myapp.free.MainActivity Переместить MainActivity на уровень выше до com.xxx.myapp.MainActivity обе версии MainActivity должны иметь одно и то же полное имя.

ОБНОВЛЕНИЕ

У вас есть два класса с именами MainActivity, но для Java они имеют разные полные имена com.xxx.myapp.free.MainActivity и com.xxx.myapp.pro.MainActivity (просто предположение).

Что вам действительно нужно, так это один класс com.xxx.myapp.MainActivity со специфическими реализациями. Вы можете добавить отдельную реализацию MainActivity для каждой разновидности с помощью путей к папкам, специфичным для этой разновидности.

app/src/free/java/com/xxx/myapp/MainActivity.java app/src/pro/java/com/xxx/myapp/MainActivity.java

Gradle будет компилировать реализацию только для выбранного варианта.

person cyroxis    schedule 02.12.2015
comment
Но мне нужна другая MainActivity для разных вкусов. - person ; 02.12.2015
comment
Хотя у меня конфликт. Импорт MainComponent приходится настраивать вручную, когда я переключаю вкусы. Явно делаю что-то не так. - person ; 02.12.2015
comment
но оба моих варианта имеют разные имена пакетов (или идентификаторы приложений), что приводит к тому, что оба MainAcitivty имеют разные полные имена. Как бы я поступил, если бы оба варианта имели разные имена пакетов? Должен ли src/java/main содержать MainAcitivity, если я хочу иметь его реализацию в обоих вариантах? Из того, что я читал, не должно. - person ; 02.12.2015
comment
Вы можете использовать отдельные идентификаторы приложений и по-прежнему обмениваться действиями. Вам просто нужно полностью указать название вашей деятельности в манифесте Android. Это означает, что вместо того, чтобы писать android:name=.MainActivity, вы должны написать android:name=com.xxx.myapp.MainActivity - person Matt Wolfe; 02.12.2015
comment
@MattWolfe android:name="com.xxx.myapp.MainActivity" работал бы, если бы у меня было MainActivity в src/java/main, не так ли? Но я не знаю. У меня есть в разных вкусовых упаковках. Или я неправильно к этому отношусь? - person ; 02.12.2015
comment
Идентификаторы приложений и конфигурации манифеста также можно настроить, добавив разные версии манифеста в папки разновидностей (см. слияние манифестов) или добавив аргументы-заполнители манифеста в файл gradle. - person cyroxis; 02.12.2015
comment
У меня есть три разных файла манифеста. Один в src/java/main, src/java/pro и src/java/free. Один бесплатный отличается от двух других тем, что я объявил метаданные для рекламы. Не могли бы вы сказать мне, какое изменение я должен внести, чтобы иметь один класс с реализациями, специфичными для вкуса? Должен ли я иметь класс во всех трех пакетах? Или только в 2х вкусах? - person ; 02.12.2015
comment
Возвращаясь к основам: Итак, если у меня есть MainActivity только в src/java/main, но мне нужна другая его реализация в src/java/free, что мне делать? - person ; 02.12.2015
comment
Мой ответ не относится к конфигурации манифеста, это отдельная проблема и может быть выполнена по-разному. Кроме того, в манифесте (наряду с другими ресурсами, такими как Strings.xml) есть специальные правила, позволяющие объединять содержимое файлов. - person cyroxis; 02.12.2015
comment
У вас не должно быть MainActivity в вашей основной папке. У вас должна быть одна реализация в каждом варианте (про, бесплатно). Gradle добавит только один к пути сборки (выбранный вами вариант). Вы можете думать об этом так, как будто gradle копирует все файлы из вашего текущего варианта в основной во время компиляции. - person cyroxis; 02.12.2015
comment
Я бы просто лично имел 1 MainActivity и определял вкус во время выполнения, stackoverflow.com/questions/23431354/ - person Matt Wolfe; 02.12.2015
comment
@cyroxis Это именно то, что я сделал, но это приводит к конфликту в MainComponent, где я могу импортировать только два аромата MainActivity - person ; 02.12.2015
comment
@MattWolfe, да, это хороший способ, но я пытаюсь ознакомиться со вкусами продуктов, и я хотел бы попробовать сделать это таким образом, чтобы учиться. - person ; 02.12.2015
comment
@stack Прочитайте из опубликованного модуля Dagger 2, который у вас есть import com.xxx.myapp.free.MainActivity; Этот модуль кинжала может предоставить классу только это точное полное имя. Если вы хотите, чтобы в кинжал вставлялась другая MainActivity для разных вкусов, вам нужны две разные реализации MainActivity. - person cyroxis; 02.12.2015
comment
Существует много разных способов настройки вашего проекта и вашего манифеста, но ваш вопрос заключался в том, как ввести два разных MainActivites в один и тот же модуль. - person cyroxis; 02.12.2015
comment
@cyroxis, у меня есть две разные реализации, но я могу импортировать только одну в класс MainComponent, который находится в src/java/main - person ; 02.12.2015
comment
@stack - Да, это было моей точкой зрения все время, поэтому вам нужны две разные реализации MainActivity (ни одна из которых не находится в main). - person cyroxis; 02.12.2015
comment
Да и у меня именно так. Но это приводит к конфликту в MainComponent, где я могу импортировать только один. Ха-ха. - person ; 02.12.2015
comment
@stack - тогда у вас его нет, как я предлагаю в своем ответе. - person cyroxis; 02.12.2015
comment
@stack Теперь я понимаю, что говорит cyroxis. Вам нужно использовать одно и то же имя пакета для обоих, не используйте free/pro внутри фактического имени пакета java.. Просто используйте тот же пакет, но внутри подпапки free/pro в источник - person Matt Wolfe; 02.12.2015

Вы можете определить вкус во время выполнения с помощью BuildConfig.FLAVOR, и оттуда вы можете выборочно добавлять рекламу, а что нет. Я бы лично сделал так.

person Matt Wolfe    schedule 02.12.2015