Пошаговое руководство по созданию этого превосходного ресурса

Table of Contents
Introduction to Android library
My Experience with Android Libraries
Prerequisites
Create an Android library
Upload the Code to Github or Bitbucket Repository
Create a Sonatype Account
Generating a GPG key pair
Setup Publication Details in the Project
Library or Module Level Gradle Setup
Sonatype Staging Profile Id Setup
First Release
Automate Creating and Release a Library version
How to Use the Published Library

Введение в библиотеку Android

Библиотека Android структурно аналогична приложению Android с файлами ресурсов, исходным кодом, файлом манифеста и так далее. Однако вместо того, чтобы компилироваться в APK, библиотека Android компилируется в файл Android Archive (AAR), который вы можете использовать в качестве зависимости, чтобы нам не нужно было создавать или писать один и тот же код снова.

Если вы какое-то время были разработчиком Android, вы должны были использовать хотя бы одну библиотеку (возможно, библиотеки androidX). Если вы видите какие-либо сайты git, у них есть много библиотек с открытым исходным кодом для таких функций, как выбор даты, загрузка изображений и т. д. Основное намерение всех этих репозиториев — повторное использование кода.

Как правило, файлы библиотек создаются в формате JAR. Мы можем использовать это в случае с Android, но единственная проблема заключается в том, что формат JAR не может включать исходный код в структуру проекта Android. Однако вместо создания JAR-файла библиотека Android компилирует его в файл Android-архива (AAR), который можно использовать в качестве зависимости в любом проекте Android.

В отличие от JAR, файл Android Archive (AAR) может объединять ресурсы Android и файл манифеста, что позволяет нам совместно использовать такие ресурсы, как файлы макетов, действия, чертежи и т. д.

Мой опыт работы с библиотеками Android

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

Я начал свое путешествие по библиотеке Android, создав файлы AAR и поделившись ими вручную с командой хост-приложения. Одним из основных недостатков этого подхода является то, что файлы AAR не будут включать сторонние библиотеки. Таким образом, разработчики библиотек должны информировать команду хост-приложений обо всех необходимых сторонних библиотеках и просить их включить зависимости в проект вручную.

Это много ручной работы для простой интеграции и объем работы, который необходимо выполнить в каждом выпуске. Затем я искал альтернативы, чтобы избежать ручной работы, и нашел два подхода: размещение библиотек в JitPack или Maven Central.

Это создаст файлы POM, которые позаботятся о загрузке необходимых сторонних библиотек, а также, просто увеличив версию в градиенте хост-приложения, можно будет импортировать новую версию библиотеки.

Чтобы узнать больше о публикации библиотек Android в Jitpack, прочитайте следующую статью:



Предпосылки

Ниже приведены инструменты, которые мы используем в процессе публикации библиотеки Android:

  • Инструмент командной строки gpgGPG Suite для macOS или Gpg4win для Windows — отличный выбор. Многие альтернативы для разных платформ доступны здесь.
  • BitBucket для размещения кода библиотеки.

Я также предполагаю, что вы знакомы с основами разработки под Android.

Создайте библиотеку Android

Начнем с создания нового проекта Android. После успешного создания проекта перейдите, как показано ниже:

Файл › Новое › Новый модуль › Android Library

Заполните данные и нажмите «Готово». Это создаст библиотечный модуль, который, по сути, является библиотекой, которую мы разместим на центральном сервере maven. Теперь вы можете увидеть модуль рядом с приложением на левой панели.

Мы только что создали подмодуль. Теперь нам нужно связать его с модулем приложения, чтобы использовать код в корневом проекте. Для этого откройте структуру проекта, выполнив навигацию, как показано ниже:

Файл › Структура проекта

Теперь выберите параметр «Зависимости» на левой панели, затем выберите приложение в разделе «Модули». Наконец, щелкните параметр «плюс» в разделе «Объявленные зависимости», а затем выберите параметр «Зависимость от модуля». Вот как это будет выглядеть:

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

Это добавит следующую строку в файл градиента сборки на уровне приложения:

implementation project(path: ':MavenLibraryOpenSource')

Загрузите код в репозиторий GitHub или Bitbucket.

Здесь мы используем Bitbucket для размещения библиотеки и корневого кода проекта. Перейдите в Bitbucket и войдите в систему, затем создайте пустой репозиторий.

Теперь перейдите в каталог субмодуля и загрузите субмодуль в созданный репозиторий. Здесь мы создаем отдельный подмодуль git вместо того, чтобы хранить корневой проект и подмодуль в одном репозитории. Чтобы узнать больше о подмодулях git, прочитайте следующую статью:



Создать учетную запись Sonatype

Теперь, когда мы закончили создание библиотеки и размещение ее на Bitbucket, следующим шагом будет создание учетной записи в Sonatype Jira. Перейдите по URL-адресу и зарегистрируйтесь, указав свой адрес электронной почты, полное имя, имя пользователя и пароль. После этого войдите в систему с теми же учетными данными.

Процесс довольно прост, но обязательно используйте только буквенно-цифровые символы в разделе имени пользователя, иначе вы столкнетесь с проблемами при выпуске библиотеки.

Создать проблему

После выбора языка и аватара вы окажетесь на этой целевой странице — нажмите «Создать задачу»:

Нам нужно создать задачу, запрашивающую доступ к идентификатору группы, под которой мы хотим опубликовать библиотеку. В зависимости от варианта использования мы можем использовать собственное доменное имя, если оно у нас есть (требуется проверка). Если нет, мы можем использовать идентификатор группы на основе битбакета (примерно так: io.bitbucket.bitbucketUsername).

После того, как вы выберете опцию «Создать задачу», вы попадете на страницу с двумя вариантами:

  1. Проект: выберите «Поддержка сообщества — Хостинг репозитория проекта с открытым исходным кодом».
  2. Тип задачи: выберите «Новый проект».

Затем нажмите Далее. Это приведет вас к следующему шагу в создании задачи, где вы должны предоставить такие детали, как сводка, описание, идентификатор группы и т. д. Давайте рассмотрим их один за другим:

  • Резюме: создайте репозиторий для your.group.id.here
  • Описание: необязательное краткое изложение того, о чем ваш проект.
  • Идентификатор группы: идентификатор вашей группы, как обсуждалось выше.
  • URL-адрес проекта: мы можем передать URL-адрес репозитория Bitbucket библиотеки.
  • URL-адрес SCM: мы можем передать URL-адрес репозитория Bitbucket библиотеки.
  • Имя пользователя (имена): Если вам нужны дополнительные пользователи, мы можем указать их имена здесь.
  • Уже синхронизировано с Central: в нашем случае мы только начинаем, так что нет.

Закончив с деталями, нажмите кнопку «Создать». Может потребоваться некоторое время, чтобы передать проблему кому-то и решить ее. Взгляните на проблему:

Надеемся, что в течение разумного времени (не более 15–30 минут) вы получите комментарий для подтверждения идентификатора домена. Поскольку мы используем идентификатор группы на основе битбакета, мы должны проверить его, создав образец репозитория. Посмотрите, как это выглядит:

После того, как вы подтвердите идентификатор группы, вы получите еще один комментарий с зеленым сигналом для перехода к размещению библиотеки в Maven Central. Взгляни:

Создание пары ключей GPG

Артефакты, опубликованные на MavenCentral, должны быть подписаны их издателями. Для этого нам понадобится ключ GPG. Эта часть требует доступа к команде gpg. Есть много способов установить это через менеджеры пакетов, и многие дистрибутивы доступны для разных платформ на gnupg.org.

После загрузки GPG Keychain перейдите в командную строку и выполните следующую команду, чтобы создать новый ключ:

gpg --full-gen-key

Вам будет предложено заполнить следующие данные:

  • Тип ключа: примите значение по умолчанию, которое равно (1) RSA and RSA.
  • Размер ключа: 4096.
  • Срок действия: введите 0, чтобы создать ключ с неограниченным сроком действия.
  • Настоящее имя, адрес электронной почты: введите свой адрес электронной почты.
  • Комментарий: Необязательно. Вы можете оставить его пустым.

Наконец, вам будет предложено ввести парольную фразу, которую вы можете нажать Enter, если не хотите использовать парольную фразу. Вот и все; все готово. Чтобы просмотреть список сгенерированных ключей, выполните следующую команду:

gpg --list-keys

Обязательно скопируйте последние восемь цифр ключа. Он понадобится вам в следующих разделах.

Теперь, когда мы создали пару открытого и закрытого ключей, нам нужно загрузить открытый ключ на сервер, чтобы любой мог проверить, принадлежит ли он вам, что вы можете сделать, выполнив следующее:

gpg --keyserver keyserver.ubuntu.com --send-keys 9AQF901D

9AQF901D — Последние восемь цифр вашего ключа.

Теперь, что касается закрытого ключа, нам нужно получить экспорт ключа base 64 для подписи артефакта. Мы можем получить формат base64, выполнив следующую команду:

gpg --export-secret-keys 9AQF901D | base64

Введите парольную фразу, которую вы создали ранее, или нажмите Enter, если парольной фразы нет. Затем скопируйте сгенерированную строку base64 во временный файл; нам это понадобится в следующих разделах.

Настройка сведений о публикации в проекте

Начнем настройку с корневого проекта. Мы должны добавить файлgradle-nexus.publish-plugininsidebuild.gradle в блок плагинов. Этот плагин легко автоматизирует публикацию позже. Взгляни:

plugins {
    id("io.github.gradle-nexus.publish-plugin") version "1.1.0"
}

Нам нужно создать файл gradle для хранения глобальной конфигурации, необходимой для публикации библиотеки. Создадим в корне подпакет с именем scripts, а затем внутри него создадим publish-root.gradle. Взгляни:

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

Добавьте следующий код в publish-root.gradle:

// Create variables with empty default values
ext["signing.keyId"] = ''
ext["signing.password"] = ''
ext["signing.key"] = ''
ext["ossrhUsername"] = ''
ext["ossrhPassword"] = ''
ext["sonatypeStagingProfileId"] = ''
  • keyId: последние восемь цифр ключа GPG, который мы сгенерировали ранее.
  • password: парольная фраза пары ключей.
  • key: формат закрытого ключа в кодировке base64.
  • ossrhUsername и ossrhPassword: данные, представленные во время регистрации в Sonatype JIRA.

Остается sonatypeStagingProfileId, о котором мы поговорим в следующих разделах.

Теперь, когда мы создали свойства с пустыми значениями, пришло время назначить данные. Мы можем сделать это двумя способами: во-первых, мы можем сохранить их в local.properties и извлечь их, или мы можем получить их из переменных среды. Взгляни:

А пока давайте добавим детали в local.properties, как показано ниже:

Последним шагом в этом файле является определение репозитория MavenCentral (Sonatype) для загрузки артефакта. Это основано на полях, полученных на предыдущем шаге. Взгляни:

Вы можете получить весь код для добавления в publish-root.gradle из этой сути.

В качестве последнего шага добавьте следующую строку в build.gradle корневого проекта, чтобы применить скрипт.

apply from: 'scripts/publish-root.gradle'

Вот и все. Это завершает часть конфигурации корневого проекта, затем следует конфигурация уровня модуля или библиотеки.

Настройка Gradle на уровне библиотеки или модуля

Что касается конфигурации на уровне модуля, давайте начнем с создания нового файла publish-remote.gradle для определения конфигурации публикации и подписи артефакта в модуле библиотеки. Взгляни:

Начнем с добавления плагинов, необходимых для публикации и подписи артефакта. Взгляни:

apply plugin: 'maven-publish'
apply plugin: 'signing'

Затем нам нужно объявить источники, чтобы убедиться, что правильные исходные файлы упакованы с исполняемым скомпилированным кодом. Взгляни:

Далее нам нужно установить два свойства: groupdID и version артефакта. Мы получим значения этих свойств из gradle уровня модуля, который мы реализуем в следующих разделах.

group = PUBLISH_GROUP_ID
version = PUBLISH_VERSION

Последним шагом является предоставление метаданных библиотеки для выпуска:

Последним шагом является получение сведений о подписи из корневого проекта и подписание артефакта. Взгляни:

signing {
    useInMemoryPgpKeys(
            rootProject.ext["signing.keyId"],
            rootProject.ext["signing.key"],
            rootProject.ext["signing.password"]
    )
    sign publishing.publications
}

Вы можете получить весь код для добавления в publish-remote.gradle из этой сути.

На этом настройка конфигурации, настроенная в publish-remote.gradle., завершена. Следующим шагом является публикация сведений, таких как идентификатор группы, версия и идентификатор артефакта, в файле gradle уровня module. Затем следует применить сам скрипт, как показано ниже:

ext {
    PUBLISH_GROUP_ID = 'io.bitbucket.username'
    PUBLISH_VERSION = '0.1'
    PUBLISH_ARTIFACT_ID = 'MavenLibraryOpenSource'
}
apply from: 'publish-remote.gradle'

Настройка идентификатора промежуточного профиля Sonatype

Теперь вернемся к sonatypeStagingProfileId, объявленному пустым в файле local.properties. Это идентификатор, который Sonatype присваивает вам, и с помощью этого идентификатора плагин обеспечивает загрузку артефактов в нужное место.

Чтобы получить sonatypeStagingProfileId, перейдите на https://s01.oss.sonatype.org и войдите в систему с учетными данными Sonatype. Теперь нажмите StagingProfiles на левой панели, выберите свой профиль, затем найдите идентификатор в URL-адресе. Взгляни:

Теперь назначьте идентификатор профиля соответствующему свойству в local.properties.

Первый выпуск

Прежде чем выпустить первую версию библиотеки, давайте создадим файл Kotlin с именем SimpleCalculator и включим две простые функции для доступа к ним при импорте библиотеки в любой проект Android.

fun add( a : Int, b : Int ) : Int {
    return a + b
}
fun multiply( a : Int, b : Int ) : Int {
    return a * b
}

Теперь, переходя к выпуску, мы можем запустить выпуск, выполнив следующую команду из корневого каталога проекта в командной строке.

./gradlew MavenLibraryOpenSource:publishReleasePublicationToSonatypeRepository

Это создаст промежуточный репозиторий, который мы можем увидеть, щелкнув параметр промежуточных репозиториев на левой панели. Взгляни:

Чтобы просмотреть все загруженные файлы, щелкните вкладку содержимого на нижней панели и перейдите по пути идентификатора группы. Если вы готовы двигаться вперед, нажмите на репозиторий и кнопку закрытия на верхней панели. Это может занять некоторое время. Вы можете увидеть прогресс на вкладке «Активность» на нижней панели. Как только он будет закрыт, вы увидите активность Repository Closed.

Как только репозиторий будет закрыт, у вас будет два варианта: удалить и выпустить. Удаление означает отмену выпуска и удаление всего репозитория. Релиз должен продвигаться вперед с публикацией новой версии библиотеки.

Если все в порядке и вы приступили к выпуску, после его завершения может потребоваться некоторое время, чтобы подумать. Мы можем проверить, работает ли библиотека, перейдя по адресу https://repo1.maven.org/maven2/io/bitbucket/user_name/MavenLibraryOpenSource/. Это покажет 404, если он еще не опубликован. Обязательно измените идентификатор группы и имя артефакта в URL-адресе.

Автоматизируйте создание и выпуск новой версии

Когда я говорю об автоматизации, я не имею в виду конвейер или CICD. Это просто способ избежать посещения пользовательского интерфейса maven для закрытия и выпуска репозитория вручную. С помощью следующей команды мы можем загрузить и выпустить артефакт.

./gradlew MavenLibraryOpenSource:publishReleasePublicationToSonatypeRepository closeAndReleaseSonatypeStagingRepository

Это не что иное, как объединение двух команд и их одновременное выполнение, чтобы избежать ручной работы.

Как использовать опубликованную библиотеку

Как только библиотека будет опубликована, мы сможем интегрировать ее в любое Android-приложение и использовать созданные в ней функции. В нашем случае это SampleCalculator. Формат интеграционного URL библиотеки:

group_id:artifact_name:version

В нашем случае это будет так, как показано ниже:

implementation "io.bitbucket.username:MavenLibraryOpenSource:0.1"

Вот и все. Вы создали свою первую библиотеку Android и опубликовали ее на MavenCentral!

Бонус

Если вас интересует разработка библиотек для Android, прочтите следующие статьи:

На данный момент - все. Надеюсь, вы узнали что-то полезное.

Спасибо за прочтение.