Создание нативных Android-библиотек с помощью новейшего экспериментального Android-плагина

Автор: | 03.08.2026

Одной из основных проблем, с которыми мы столкнулись при разработке NDK для нашего Android Video SDK, стала интеграция с предписанным Android Studio рабочим процессом на основе Gradle. Наша главная трудность заключалась в отладке нативных компонентов внутри Android-библиотеки. Последние обновления Android Studio и Android Gradle Plugin показывают, что Google инвестирует в улучшение опыта разработчиков для нативной разработки на Android и обеспечивает её полноценную поддержку в своей флагманской IDE. Мы внимательно следили за прогрессом этого нового плагина. Недавнее добавление поддержки статических библиотек побудило нас глубоко изучить миграцию с традиционного рабочего процесса на основе Application.mk, Android.mk и ndk-build. Мы решились на этот шаг и хотим поделиться некоторыми нашими находками в процессе перехода на новый рабочий процесс сборки.

Новый экспериментальный плагин должен быть знаком пользователям Gradle и тем, кто знаком с процессом сборки NDK. Большинство привычных флагов доступны в модели `android.ndk`. Полная документация Google по экспериментальному плагину доступна здесь.

Мы подготовили пример процесса миграции, который отражает некоторые из проблем, с которыми мы столкнулись и которые не упоминаются в текущей документации. В разделах ниже приведены примеры микроконверсий, чтобы вы могли воссоздать свои .mk-файлы в build.gradle.

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

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

1. Использование отладочных сборок наших нативных зависимостей

2. Включение статических библиотек

3. Обработка зависимостей зависимостей (foo.a зависит от bar.a)

4. Объявление целой статической библиотеки (—whole-archive)

Вот файл Android.mk, который демонстрирует каждую из этих проблем:

Для подключения статических библиотек требуется добавление записей libs в нашу модель репозиториев. Следующий фрагмент кода демонстрирует решения для первой и второй проблем. Обратите внимание на отсутствие my-whole-static-library.

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

— Обработка зависимостей зависимостей (foo.a зависит от bar.a)

— Объявление целой статической библиотеки (—whole-archive)

Решения для этих проблем несколько сложнее, и вот почему:

**Первое предположение**

Предположим, что нам не нужна `whole-static-library`, и мы можем просто продолжить с нашими двумя другими статическими библиотеками, но, как уже упоминалось, `my-other-static-library` зависит от `my-static-library`. Это означает, что если бы мы попытались скомпилировать, Gradle пожаловался бы на невозможность разрешения символов на этапе компоновки. Мы могли бы добавить `whole-static-library` в наш массив `ldLibs`, но нет механизма для указания конкретной архитектуры.

**Второе предположение**

Предположим, что третьей проблемы не существует, и мы добавляем `whole-static-library` так же, как и другие. Мы смогли бы скомпилировать, но столкнулись бы с исключениями «метод не найден», если бы вызывали нативные методы из Java-слоя, потому что компилятор удалит функции, которые он считает неиспользуемыми. Мы могли бы вручную добавить whole-static-library в ldFlags, обернув его в `—whole-archive`, но опять же, у нас нет возможности указать архитектуру.

Решения для третьей и четвёртой проблем потребовали некоторых исследований конфигурации модели на основе правил, находящейся на стадии инкубации в Gradle, и понимания задач, генерируемых экспериментальным плагином. Если выполнить команду ./gradlew tasks —all в нашем примере, можно обнаружить следующее:

Эти задачи посвящены компоновке, и если мы изменим аргументы, передаваемые компоновщику, то сможем решить третью и четвёртую проблемы: обработку зависимостей зависимостей и объявление целой статической библиотеки. Создав RuleSource, мы можем применять мутации к моделям в конфигурации Gradle. Вот фрагмент кода, показывающий, как изменить каждую из этих задач компоновки. Этот фрагмент можно добавить в конец файла build.gradle:

Существует несколько публикаций о создании Javadoc для проектов Android-библиотек, но они не применимы к этому новому экспериментальному плагину. Вот простой фрагмент для добавления задачи создания Javadoc в ваш проект:

Хотя процесс оказался несколько сложнее, чем мы ожидали, миграция на экспериментальный плагин оказалась гораздо более подходящей для нативной разработки на Android. Дополнительные преимущества, такие как автодополнение кода, гибридный режим отладки и гибкость Gradle, принесли значительные улучшения в эффективности разработки нашего Android SDK. Несмотря на то что плагин помечен как экспериментальный, его стабильность впечатляет, а интеграция с Android Studio 2.0 проходит безупречно. К сожалению, документация по плагину немного скудна, и начальный этап может быть пугающим, но в целом преимущества стоят затраченных усилий.

*Подписывайтесь на Аарона Аланиза в Twitter здесь @webheadz3.*