Додаток із декількома смаками на основі бібліотеки з кількома смаками в Android Gradle


102

У моїй програмі є кілька ароматів для декількох ринків систем виставлення рахунків.

У мене є єдина бібліотека, яка розділяє базовий код для всіх моїх проектів. Тому я вирішив додати ці платіжні системи до цієї бібліотеки як аромат продуктів.

Питання в тому, чи може андроїдна бібліотека мати ароматизатори продуктів?

Якщо так, то як я можу включати різні смаки у відповідний смак програми?

Я багато шукав, і нічого не вдалося знайти про цей сценарій. Єдине близьке, що я знайшов, це це у http://tools.android.com/tech-docs/new-build-system/user-guide :

dependencies {
    flavor1Compile project(path: ':lib1', configuration: 'flavor1Release')
    flavor2Compile project(path: ':lib1', configuration: 'flavor2Release')
}

Я змінив конфігурацію на різні речі, але це не спрацювало!

Я використовую android studio 0.8.2.


після багатьох пошуків я не знайшов способу досягти цього, навіть я модернізував плагін Android до найновішої 3.4.2версії та gradle до останнього 5.5.1, він все ще не вдався до часу компіляції, або зв’язок ресурсів не вдався в aapt, або не можу знайти символ, який знаходиться всередині бібліотеки модуль
VinceStyling

Відповіді:


141

Нарешті я з'ясував, як це зробити, я поясню це для інших, що стикаються з тією ж проблемою:

Ключова частина полягає у встановленні для publicNonDefault істинного в бібліотеці build.gradle, тоді ви повинні визначити залежності, як запропоновано керівництвом користувача.

Весь проект був би таким:

Бібліотека build.gradle:

apply plugin: 'com.android.library'

android {        
    ....
    publishNonDefault true
    productFlavors {
        market1 {}
        market2 {}
    }
}

проект build.gradle:

apply plugin: 'com.android.application'

android {
    ....
    productFlavors {
        market1 {}
        market2 {}
    }
}

dependencies {
    ....
    market1Compile project(path: ':lib', configuration: 'market1Release')
    market2Compile project(path: ':lib', configuration: 'market2Release')
}

Тепер ви можете вибрати смак програми та панель «Варіанти збирання», і бібліотека буде вибрана відповідно, і все збирання та запуск буде виконано на основі вибраного аромату.

Якщо у вас є декілька модулів додатків на основі бібліотеки Android Studio буде скаржитися на конфлікт вибору варіантів, це нормально, просто проігноруйте його.

введіть тут опис зображення


Дякуємо, що поділилися, тепер я можу позбутися мого вирішення за замовчуваннямPublishConfig.
Дельбланко

2
Запуск 1.1.0, здається, що вищезгадане рішення все ще працює, однак 1) вибір налагодження / випуску будується втрачено, і, здається, у бібліотеці виникають проблеми з AIDL, які дуже часто не вдається створити відповідний код. Будь-які думки з цього приводу?
3c71

1
@IgorGanapolsky buildTypes не має нічого спільного з цим. Кожен аромат має всі типи збірки (як правило, налагодження та випуск), і всі вони працюють з таким підходом.
Алі

1
@ Ан-дроїд визначає бібліотеку, яку потрібно використовувати для аромату market1!
Алі

1
Чому його встановлено на "випуск" типу збірки? Чи вибрано тип збірки "реліз" під час збирання налагодження?
WindRider

35

Є одна проблема з відповіддю Алі . Ми втрачаємо один дуже важливий вимір у наших варіантах складання. Якщо ми хочемо мати всі параметри (у моєму прикладі нижче 4 (2 x 2)), нам просто потрібно додати спеціальні конфігурації у файл головного модуля build.gradle, щоб мати можливість використовувати всі мульти-ароматичні multi-buildType в Build Variants. Ми також повинні встановити trueNonDefault true у файлі бібліотеки build.gradle .

Приклад рішення:

Lib build.gradle

android {

    publishNonDefault true

    buildTypes {
        release {
        }
        debug {
        }
    }
    productFlavors {
        free {
        }
        paid {
        }
    }
}

Build build.gradle

android {

    buildTypes {
        debug {
        }
        release {
        }
    }
    productFlavors {
        free {
        }
        paid {
        }
    }
}

configurations {
    freeDebugCompile
    paidDebugCompile
    freeReleaseCompile
    paidReleaseCompile
}

dependencies {

    freeDebugCompile project(path: ':lib', configuration: 'freeDebug')
    paidDebugCompile project(path: ':lib', configuration: 'paidDebug')
    freeReleaseCompile project(path: ':lib', configuration: 'freeRelease')
    paidReleaseCompile project(path: ':lib', configuration: 'paidRelease')

}

Виконуючи ті самі речі в моїй заявці Error:java.lang.RuntimeException: Error: more than one library with package name, що відбулося
Четан Джоші

21

Оновлення для Android Plugin 3.0.0 та новіших версій

Згідно з офіційною документацією на Android - конфігурації міграції залежностей для локальних модулів ,

З роздільною здатністю залежності залежно від варіантів, вам більше не потрібно використовувати конфігурації для конкретних варіантів, такі як freeDebugImplementation, для локальних модульних залежностей - плагін дбає про це для вас

Натомість слід налаштувати свої залежності так:

dependencies {
    // This is the old method and no longer works for local
    // library modules:
    // debugImplementation project(path: ':library', configuration: 'debug')
    // releaseImplementation project(path: ':library', configuration: 'release')

    // Instead, simply use the following to take advantage of
    // variant-aware dependency resolution. You can learn more about
    // the 'implementation' configuration in the section about
    // new dependency configurations.
    implementation project(':library')

    // You can, however, keep using variant-specific configurations when
    // targeting external dependencies. The following line adds 'app-magic'
    // as a dependency to only the "debug" version of your module.

    debugImplementation 'com.example.android:app-magic:12.3'
}

Тож у відповіді Алі змінити

dependencies {
    ....
    market1Compile project(path: ':lib', configuration: 'market1Release')
    market2Compile project(path: ':lib', configuration: 'market2Release')
}

до

implementation project(':lib')

А плагін автоматично піклується про конкретні конфігурації. Сподіваємось, це допомагає іншим, що оновлюють плагін Android Studio до версії 3.0.0 та новіших.


7

Мій плагін Android 3.4.0, і я вважаю, що йому зараз не потрібні конфігурації. Все, що вам потрібно, це переконатися, що ароматРазміри та продукт Ароматизатори в додатку містять один продукт Аромат однакового аромату Розміри та Аромат продукту в бібліотеках. Для зразка:

У мій бібліотеці build.gradle

apply plugin: 'com.android.library'

android {        
    ....
    flavorDimensions "mylibFlavor"

    productFlavors {
        market1
        market2
    }
}

build.gradle програми:

apply plugin: 'com.android.application'

android {
    ....
    flavorDimensions "mylibFlavor", "appFlavor"
    productFlavors {
        market1 {
            dimension "mylibFlavor"
        }
        market2 {
            dimension "mylibFlavor"
        }
        common1 {
            dimension "appFlavor"
        }
        common2 {
            dimension "appFlavor"
        }
    }
}

dependencies {
    ....
    implementation project(path: ':mylibrary')
}

Після синхронізації ви можете переключити всі параметри у вікні варіантів збірки: введіть тут опис зображення


Але що робити, якщо я не хочу мати однакові аромати в основному модулі додатка? Припустимо, у мене є декілька модулів додатків, які мають свої специфічні смаки, і один загальний модуль, який має власні аромати, і я хочу використовувати у своєму додатку мою конфігурацію із специфічним ароматом. Як би ти це зробив? Немає сенсу копіювати свої смакові якості на всі програми.
Білда

@Billda Вам не потрібно копіювати все, просто зберігайте один і той же продуктFlavor у додатку, для мого зразка я можу зберегти market1 або market2 у build.gradle програми.
JiajiaGu

2

Щоб отримати аромати, що працюють над бібліотекою AAR, вам потрібно визначити defaultPublishConfig у файлі build.gradle модуля бібліотеки Android.

Для отримання додаткової інформації див: Публікація бібліотеки .

Видання бібліотеки

За замовчуванням бібліотека публікує лише свій варіант випуску. Цей варіант буде використовуватися у всіх проектах, що посилаються на бібліотеку, незалежно від того, який варіант вони будують самі. Це тимчасове обмеження через обмеження Gradle, які ми працюємо над усуненням. Ви можете контролювати, який варіант публікується:

android {defaultPublishConfig "налагодження"}

Зауважте, що ця назва конфігурації публікації посилається на повне ім'я варіанта. Випуск та налагодження застосовні лише тоді, коли ароматизаторів немає. Якщо ви хочете змінити опублікований за замовчуванням варіант, використовуючи аромати, ви напишете:

android {defaultPublishConfig "taste1Debug"}


1

Наразі це неможливо, хоча якщо я правильно пригадую його функцію, яку вони хочуть додати. (Редагувати 2: посилання , link2 )

Редагувати: На даний момент я використовую defaultPublishConfigопцію, щоб оголосити, який варіант бібліотеки публікується:

android {
    defaultPublishConfig fullRelease
    defaultPublishConfig demoRelease 
}

1
Отже, кожного разу, коли я збиратиму програму, я повинен змінити це у build.gradle бібліотеки?
Алі

Ну так ... щоразу, коли ви хочете скласти додаток з іншим смаком.
Дельбланко

Насправді, коли я визначаю аромати для модуля бібліотеки, успадкований пакет R не знайде модуля програми.
Алі

Ви синхронізували файли gradle в AS?
Дельбланко

@Delblanco Це здається ручним працею і дуже крихким (розробники лінуються і забувають змінювати свої файли build.gradle).
ІгорГанапольський

1

Я знаю, що ця тема закрита, але лише оновлення з gradle 3.0 див. Тут: https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html#variant_aware and grep matchingFallbacksі missingDimensionStrategy. Тепер простіше заявити про залежності між модулями ароматів.

... і в цьому точному випадку з gradle3.0, оскільки аромати мають однакову назву, Gradle магічно відображатиме їх, конфігурація не потрібна.


Мені здається, що те, що генерується в процесі роботи, пропускається. Як приклад, генерація схем simonvt-> вже не працює з новим для мене способом. : - /
Стефан Спрінгер

1

Я також зіткнувся з проблемою компіляції модулів для різних варіантів.

Що я знайшов:

Схоже, нам не потрібно додавати publishNonDefault trueу build.gradleфайл lib , оскільки Gradle 3.0.1 .

Після декомпіляції клас BaseExtensionвиявив таке:

public void setPublishNonDefault(boolean publishNonDefault) {
   this.logger.warn("publishNonDefault is deprecated and has no effect anymore. All variants are now published.");
}

І замість:

dependencies {
...
   Compile project(path: ':lib', configuration: 'config1Debug')
}

Ми повинні використовувати:

dependencies {
...
   implementation project(':lib')
}

Важливо лише додати configurations {...}частину до build.gradle.

Отже, остаточним варіантом build.gradleфайлу програми є:

buildTypes {
   debug {
      ...
   }

   release {
      ...
   }
}

flavorDimensions "productType", "serverType"
productFlavors {
   Free {
      dimension "productType"
      ...
   }
   Paid {
      dimension "productType"
      ...
   }
   Test {
      dimension "serverType"
      ...
   }
   Prod {
      dimension "serverType"
      ...
   }
}

configurations {
   FreeTestDebug
   FreeTestRelease
   FreeProdDebug
   FreeProdRelease
   PaidTestDebug
   PaidTestRelease
   PaidProdDebug
   PaidProdRelease
}

dependencies {
   implementation fileTree(dir: 'libs', include: ['*.jar'])
   implementation project(':lib')
   ...
}

Також ви можете використовувати варіанти фільтру для обмеження варіантів складання.

Ps не забудьте включити у settings.gradleфайл модулі , наприклад:

include ':app'
include ':lib'
project(':lib').projectDir = new File('app/libs/lib')

сер, чи можете ви пояснити, як сценарій визначатиме погоду для включення бібліотеки до певної конфігурації чи ні? я маю на увазі, що у мене є випадок, коли мені потрібно використовувати печиво для певного аромату, але мені не потрібно використовувати його для іншого аромату
Jenya Kirmiza

Не потрапив у таку ситуацію. Але розробник google tutorial.android.com/studio/build/dependitions рекомендує додати префікс перед командою "імплементація" в блок "залежності {...}". Тобто залежності {paidImplementation project (': lib')}, або залежності {debugImplementation project (': lib')}, або будь-які множинні варіанти комбінованих варіантів {paidProdDebugImplementation project (': lib')}. Перевірте це та дайте нам відгук :)
Серхіо,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.