Публикация нескольких библиотек Android как одной с помощью Fused Library

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

Плагин Fused Library, входящий в комплект Android Gradle Plugin, помогает упаковать несколько модулей Android Library в единую библиотеку Android, готовую к публикации. Это позволяет вам модулировать исходный код и ресурсы вашей библиотеки в вашей сборке по своему усмотрению, избегая при этом раскрытия структуры проекта после его распространения.

Распространение в виде единой библиотеки может иметь следующие преимущества:

  • Упрощенные зависимости: заменяет несколько библиотечных зависимостей одним AAR, оптимизируя настройку проекта и управление версиями для ваших пользователей.
  • Уменьшенный размер библиотеки: может улучшить сжатие кода, что приведет к уменьшению размера AAR.
  • Улучшенная безопасность: обеспечивает лучший контроль над внутренними деталями реализации опубликованных библиотек.

Создать объединенную библиотеку

Чтобы создать объединенную библиотеку, вам необходимо создать новый модуль Android, добавить зависимости, а затем опубликовать объединенную библиотеку.

Добавить новый модуль объединенной библиотеки

Чтобы использовать плагин, необходимо добавить в свой проект новый модуль Android:

В этом примере модуль объединенной библиотеки будет называться myFusedLibrary .

  1. Включите поддержку fusion-библиотек, добавив android.experimental.fusedLibrarySupport=true в файл gradle.properties .
  2. Добавьте include(":myFusedLibrary") в файл settings.gradle.kts .
  3. Добавьте android-fusedlibrary = { id = "com.android.fused-library", version.ref = "agp" } в раздел [plugins] файла gradle/libs.versions.toml .
  4. Добавьте alias(libs.plugins.android.fusedlibrary) apply false в блоке плагинов в файле build.gradle.kts верхнего уровня.
  5. Чтобы создать модуль myFusedLibrary , создайте новый каталог с именем myFusedLibrary (щелкните правой кнопкой мыши «Мое приложение» > Создать > Каталог).
  6. Создайте файл build.gradle.kts в модуле myFusedLibrary (щелкните правой кнопкой мыши модуль myFusedLibrary > Создать > Файл).
  7. Вставьте следующее в файл myFusedLibrary/build.gradle.kts :

Котлин

plugins {
    alias(libs.plugins.android.fusedlibrary)
    `maven-publish`
}

androidFusedLibrary {
    namespace = "com.example.myFusedLibrary"
    minSdk = 21
}

dependencies { }

Круто

plugins {
    id 'fused-library'
}

androidFusedLibrary {
    namespace 'com.example.myFusedLibrary'
    minSdk 21
}

dependencies {

}

Добавить зависимости

Основная функциональность библиотеки Fusion — объединение зависимостей. Плагин поддерживает добавление локальных зависимостей проекта и внешних библиотек. Чтобы указать зависимости, которые необходимо упаковать, используйте конфигурацию include . Транзитивные зависимости не упаковываются.

Например:

Котлин

dependencies {
    include(project(":image-rendering"))
    include("mycoolfonts:font-wingdings:5.0")
}

Круто

dependencies {
    include project(':image-rendering')
    include 'mycoolfonts:font-wingdings:5.0'
}

Опубликуйте свою объединенную библиотеку

Перед публикацией объединённой библиотеки вам следует ознакомиться с публикацией библиотеки Android . Публикация объединённой библиотеки аналогична публикации библиотеки Android, однако есть несколько ключевых отличий, которые необходимо учитывать для корректной публикации объединённой библиотеки:

  • Плагин Maven Publish также должен быть применен к любому модулю, к которому применен плагин Fused Library.
  • Публикация должна наследовать от fusedLibraryComponent , поскольку это обеспечивает требуемые зависимости, необходимые для компиляции артефакта fusion-библиотеки.

Вот пример конфигурации публикаций:

Котлин

plugins {
    alias(libs.plugins.android.fusedlibrary)
    `maven-publish`
}

androidFusedLibrary {  }

dependencies {  }

publishing {
    publications {
        register<MavenPublication>("release") {
             groupId = "my-company"
             artifactId = "my-fused-library"
             version = "1.0"
             from(components["fusedLibraryComponent"])
        }
    }
}

Круто

plugins {
    id 'fused-library'
    id 'maven-publish'
}

androidFusedLibrary {  }

dependencies {  }

publishing {
    publications {
        release(MavenPublication) {
            groupId = "my-company"
            artifactId = "my-fused-library"
            version = "1.0"
            afterEvaluate {
            from components.fusedLibraryComponent
        }
    }
}

Опубликуйте свою объединенную библиотеку для тестирования

Вам следует протестировать зависимость от опубликованной библиотеки Fused из приложения или библиотеки Android. Рекомендуемый метод — опубликовать Fused библиотеку, а её зависимости проекта — в локальном репозитории Maven.

Чтобы опубликовать артефакты объединенной библиотеки в локальном репозитории, определите конфигурацию, подобную следующей:

Котлин

plugins {
    alias(libs.plugins.android.fusedlibrary)
    `maven-publish`
}

repositories {
    maven {
        name = "myLocalRepo"
        url = uri(layout.buildDirectory.dir("myLocalRepo"))
    }
}

Круто

plugins {
    id 'fused-library'
    id 'maven-publish'
}

repositories {
    maven {
        name 'myLocalRepo'
        url layout.buildDirectory.dir('myLocalRepo')
    }
}

Загрузите вашу объединенную библиотеку

Чтобы распространить вашу объединенную библиотеку, см. раздел Загрузка вашей библиотеки .

Поведение и меры предосторожности

Объединение библиотек Android имеет свои сложности, из-за которых плагину может быть сложно определить приоритеты. Например, две библиотеки с одинаковым classpath приведут к сбою сборки при слиянии библиотек. При слиянии ресурсов порядок зависимостей, указанный при выборе ресурса с одинаковым именем в разных библиотеках, будет учитываться.

  • Объединенные библиотеки могут быть опубликованы только как артефакт библиотеки Android AAR для добавления в качестве зависимости.
  • Объединение библиотек, использующих привязку данных, не поддерживается.
  • Невозможно объединить несколько типов сборки и вариантов продукта в одной объединённой библиотеке. Создайте отдельные объединённые библиотеки для разных вариантов.

Чтобы сбалансировать объём необходимой настройки и простоту использования, плагин либо откажется от сборки при возникновении неоднозначных конфликтов, либо будет использовать эвристический анализ при слиянии артефактов. Подробная информация о том, как происходит слияние артефактов, представлена в следующей таблице:

Тип Поведение
Классы Библиотеки с одинаковым classpath приведут к сбою сборки при объединении библиотеки.
Ресурсы Android Объединение ресурсов будет учитывать порядок зависимостей, указанный при выборе ресурса с одинаковым именем в разных.
Метаданные AAR Версии метаданных AAR объединяются с учётом наивысшего значения из каждой библиотеки зависимостей. Для переопределения этих значений предусмотрен DSL.

Котлин

 androidFusedLibrary { aarMetadata { minCompileSdk = 21 minCompileSdkExtension = 1 } }
Ресурсы Java Размещение файлов ресурсов Java в нескольких библиотеках с одинаковыми путями не допускается и приведет к сбою сборки.

Известные проблемы

Fused Library — это новый плагин, и в нем есть известные проблемы, над которыми ведутся работы для удовлетворения всех вариантов использования.

  • Исходные JAR-файлы не могут быть созданы
  • Добавление зависимостей файлов от других файлов .aar
  • Нет поддержки объединения артефактов RenderScript и Prefab.

Понимание зависимостей объединенной библиотеки

Библиотека Fused не имеет исходных кодов и фактически использует библиотеки Android в качестве единственного источника. Важно понимать, что и откуда берётся. Чтобы составить список зависимостей, включённых в итоговый артефакт, и зависимостей, необходимых для сборки артефакта, выполните задачу gradle :report для библиотеки Fused. Эта задача создаёт отчёт в формате JSON, который сохраняется в каталоге build/reports библиотеки Fused.

Для получения дополнительной информации о внутренних зависимостях плагина запустите задачу gradle :dependencies , чтобы просмотреть состояние конфигураций плагина.