Как импортировать один класс из другого варианта сборки

Структура моего проекта выглядит следующим образом:

+ src
        + main // this is my common code
            + java 
                - LoginScreen // depending on condition launch screen from flavor1 or flavor2 
            + res
        + flavor1
            + java
            + res
        + flavor2
            + java
            + res

У меня есть класс входа в main/src, в зависимости от условия, мне нужно запустить экран из аромата1 или аромата2.

Например:

class LoginScreen{
......

    if(true){
        // launch ScreenUser from Flavor1 reset of screen flows from falvour1
    }else{
       // launch ScreenOTP from Flavor2 reset of screen flows from falvour2
    }
}

В этом случае, если я делаю сборку для flavor1, она показывает ошибку для класса falvor2 и наоборот.

Оба варианта имеют разные идентификаторы приложения, такие как applicationIdSuffix ".flavor1".

Это возможно? Если нет, как я могу этого добиться?


comment
если вам нужно запустить, скажем, UserScreen, поместите UserScreen.java в оба варианта и поместите туда соответствующие реализации. Затем просто вызовите его с экрана входа в систему.   -  person gitter    schedule 05.01.2017
comment
Почему бы вам не определить это с помощью идентификатора приложения? Это уникально   -  person M D    schedule 05.01.2017
comment
Вы пытаетесь открыть ClassA во флейворе1 и classB в флейворе2, если это правда, и наоборот? В этом случае вы должны оставить оба класса в основном и иметь разные классы в обоих вариантах, которые решают, какой экран запускать, на основе предоставленного вами значения (т.е. что делает блок if).   -  person gitter    schedule 05.01.2017


Ответы (2)


Когда я делал подобные вещи, я использовал интерфейсы и внедрение зависимостей (я использую dagger) . Что-то типа:

public interface LoginBehaviour {

    void goToNextScreen(Context context);
}

Затем определите реализацию в каждом варианте, которая содержит код для запуска следующего экрана. Что-то типа:

public class FlavourOneLoginBehaviour implements LoginBehaviour {

    @Override
    public void goToNextScreen(Context context) {
        context.startActivity(new Intent(context, ScreenUser.class));
    }

}

А также:

public class FlavourTwoLoginBehaviour implements LoginBehaviour {

    @Override
    public void goToNextScreen(Context context) {
        context.startActivity(new Intent(context, ScreenOTP.class));
    }

}

Вам нужно настроить свой контейнер внедрения зависимостей в каждом варианте так, чтобы он ссылался на локальную реализацию (это зависит от того, какую структуру вы используете). После того, как вы это сделаете, вы можете использовать контейнер в основном проекте, чтобы получить правильную реализацию интерфейса LoginBehaviour во время выполнения, и вы можете вызвать для него goToNextScreen для навигации. Внедрение зависимостей — это действительно удобный способ убедиться, что вы можете заменять части своего кода без серьезного рефакторинга, и это очень помогает с повторным использованием и гибкостью. Надеюсь, это поможет!

person GeordieMatt    schedule 05.01.2017
comment
Спасибо, приятель, я решил это, используя неявное намерение - person N J; 05.01.2017
comment
@GeordieMatt, насколько я понял, интерфейс помещается в основной вариант, а каждая реализация - в соответствующий вариант. Но я не могу знать, как работает DI для ссылки на локальную реализацию. Не могли бы вы поделиться фрагментом кода настройки контейнера для внедрения зависимостей в каждом варианте? - person Charan; 28.02.2018
comment
@Charan Лучше всего для этого подойдет документация для вашей инфраструктуры DI. Я бы рекомендовал Dagger для Android-приложений (ссылка в ответе). - person GeordieMatt; 02.03.2018

Одна из возможностей сделать это, если вы хотите иметь только один класс с if, который проверяет ваш buildType/productFlavor - вы можете установить значение поля BuildConfig в обоих buildTypes/productFlavors, добавив:

productFlavors {
  flavor1 {
    buildConfigField "String", "BUILD_FLAVOR", "Flavor1"
  }
  flavor2 {
    buildConfigField "String", "BUILD_FLAVOR", "Flavor2"
  }
}

И тогда вы можете использовать его в коде:

class LoginScreen {
......

  switch(BuildConfig.BUILD_FLAVOR) {
    case "Flavor1":
      // launch ScreenUser from Flavor1
      break;
    case "Flavor2":
      // launch ScreenOTP from Flavor2
      break;
  }
}

Надежда, я помог. Удачи!

person NonGrate    schedule 05.01.2017
comment
Пробовал и это, но он показывает ошибку компиляции при импорте для ScreenUser, если я сделал сборку с ароматом2 - person N J; 05.01.2017
comment
Не могли бы вы опубликовать здесь сведения об ошибках компиляции? К сожалению, я даже предположить не могу, какая там может быть проблема. Спасибо! - person NonGrate; 05.01.2017
comment
Это дает мне ошибку при импорте Activity из оператора импорта flavro1. Error:(17, 55) error: package com.mypackage.views.product_selection does not exist так как это действие из другой разновидности - person N J; 05.01.2017
comment
Если вы хотите использовать разные классы для разных вкусов - вы должны либо иметь LoginScreen в каталогах вкусов и реализовывать каждый вкус отдельно, либо вы можете иметь все классы для обоих вкусов в главном каталоге и использовать мой подход с switch или ifs - person NonGrate; 05.01.2017
comment
Спасибо, приятель, я решил это, используя неявное намерение - person N J; 05.01.2017