Изменение моих источников в соответствии с параметрами сборки - PullRequest
0 голосов
/ 09 октября 2018

TL; DR: Какой будет чистый способ изменить мои источники в зависимости от параметров, передаваемых в gradle?


Я создаю приложение для Android, которое зависит от библиотеки A,Я хотел бы иметь возможность поддерживать несколько версий A (допустим, я хочу поддерживать как v1, так и v2).Я имею в виду, что хочу иметь возможность создавать myapp-withAv1.apk и myapp-withAv2.apk.

. Я видел, что во время компиляции легко выбрать версию A, которую я хочу (Например, я могу сослаться на эту версию в переменной моего файла build.gradle, а затем запустить сборку с ./gradlew -PversionOfA=v1 build).

Но другая сложность заключается в том, что A может изменить свой открытый API, поэтому япотребуется изменить мой код в соответствии с версией, которую я создаю против.Было бы легко, если бы я занимался C ++ или C # (спасибо #ifdef), но я не смог найти способ сделать это без слишком большого дублирования кода, и я был бы не в восторге, если бы вы могли указать мне путьчтобы достичь этого.

(Обратите внимание, что попытка изолировать ветвь кода с помощью чего-то вроде if(version == v1) не работает, так как это приведет к ветке кода, которая вызовет метод A, который недоступенпоэтому сборка не удалась)

Ответы [ 2 ]

0 голосов
/ 23 апреля 2019

У меня были аналогичные потребности при разработке для J2ME в 2002 году, так что я разработал препроцессор , сегодня он поддерживает maven, gradle и ant, вы можете попробовать его для Android, тестового проекта Android, который может бытьиспользуемый в качестве образца можно найти в репозитории проекта В случае препроцессора исходные коды Java выглядят так

0 голосов
/ 10 октября 2018

Я столкнулся с подобной проблемой, ответ productFlavors в Android или sourceSets для универсального банку.В основном вам нужно указать реализацию для интерфейса в каждом наборе исходных кодов.

# define the interface in the main
/src/main/java/com/me/IMyInterface.java
# create a v1 and v2 sourceset with the implementation, note paths are the same
/src/v1/java/com/me/MyImplementation.java
/src/v2/java/com/me/MyImplementation.java

Теперь в вашем gradle определите productFlavors

android {
    productFlavors {
        v1 {
            buildConfigField 'string', 'FLAVOR', 'v1'
        }
        v2 {
            buildConfigField 'string', 'FLAVOR', 'v2'
        }
    }
    //...
}

Теперь, когда вы ссылаетесь на реализацию, вы получите sourceSet для версии, определенной в качестве названия продукта.

// since the package is the same we are unaware of which we are calling
// now we can treat them as the same regardless of the underlying
// implementation differences between v1/v2

import com.me.MyImplementation;

public String doSomethingWithImplementation() {

    MyImplementation impl = new MyImplementation();

    // here if we are executing in the productFlavor v1
    // apk we get the code from the v1 folder, same for v2 apk
    return impl.doSomething()
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...