Фон
Несколько месяцев назад я написал базу данных Key-Value для Android под названием SnappyDB на основе Google LevelDB . Поскольку он использует собственный код C ++, сгенерированный пакет содержит ( .so ) двоичные библиотеки libs вместе с Jars.
Распространение через репозиторий Maven не является проблемой (Как только вы пропустите хлопоты по процессу публикации :), maven-android-plugi n поможет вам включить общие библиотеки. Соглашение о зависимостях Maven позволяет вам указать тип ABI (разные архитектуры ЦП) и формат библиотеки (в нашем случае, очевидно, .so), которую вы хотите разрешить, используя классификатор:
Пример: разрешение общей библиотеки ARM для SnappyDB:
<dependency>
<groupId>com.snappydb</groupId>
<artifactId>snappydb-native</artifactId>
<version>0.2.0</version>
<classifier>armeabi</classifier>
<type>so</type>
</dependency>
Этот подход прекрасно работает, если вы используете Maven & Eclipse ADT в качестве системы сборки, пока не уступите вызову сирены Gradle!
Android Studio & Gradle
Плагин Android Gradle, корректно обрабатывает все зависимости Jars с помощью репозиториев Maven (среди прочего …)
пример : объявление зависимости внутри build.gradle
dependencies {
classpath 'commons-io:commons-io:2.4'
}
но он сталкивается с трудностями, когда дело касается нативных зависимостей, по сравнению с Maven, вы не можете написать что-то вроде этого:
dependencies {
classpath 'com.snappydb:snappydb-native:2.+:arm-v7a'
}
Это связано с тем, что поддержка NDK все еще находится в стадии разработки с плагином Android. (как с Android Studio).
jniLibs на помощь!
В версии 0.7.2 плагина для Android Google представил новую папку « jniLibs » для исходных наборов. Это означает, что теперь вы можете добавить свои предварительно созданные файлы .so в эту папку, а плагин Android позаботится об упаковке этих собственных библиотек в ваш APK.
.
├── AndroidManifest.xml
└── jniLibs
├── armeabi
│ └── libsnappydb-native.so
├── armeabi-v7a
│ └── libsnappydb-native.so
├── mips
│ └── libsnappydb-native.so
└── x86
└── libsnappydb-native.so
Эта функция великолепна, но разработчику все равно нужно вручную загружать и копировать свои предварительно созданные файлы .so , что не очень хорошо, особенно если вы используете сервер непрерывной интеграции, например, Jenkins или Travis.
Появилось много хаков и обходных путей , чтобы попытаться разобраться в этом, но многие из них действительно многословны и требуют, чтобы пользователь вручную загружал свои родные зависимости.
Итак, вы получите картину. Там должен быть лучший способ.
Встречайте android-native-зависимости
android-native-dependencies — это плагин Gradle, который я написал для автоматизации процесса разрешения, загрузки и копирования собственных зависимостей в папку jniLibs , поэтому плагин Android может автоматически включать их в сборку APK.
Плагин использует тот же репозиторий, который объявлен для разрешения обычных зависимостей (jar). Вот пример:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.10.+'
classpath 'com.nabilhachicha:android-native-dependencies:0.1'
}
}
apply plugin: 'android'
apply plugin: 'android-native-dependencies'
native_dependencies {
artifact 'com.snappydb:snappydb-native:0.2+:armeabi'
artifact 'com.snappydb:snappydb-native:0.2+:x86'
}
dependencies {
//regular Jar dependencies ...
}
условность
DSL артефакта следует соглашению об именовании для артефактов Maven. Таким образом, вы можете использовать один из следующих синтаксисов:
- сокращенная группа: имя: версия [: классификатор]
//adding x86 classifier will resolve only intel's (.so) lib
native_dependencies {
artifact 'com.snappydb:snappydb-native:0.2+:x86'
}
//omit the classifier will resolve all supported architectures
native_dependencies {
artifact 'com.snappydb:snappydb-native:0.2+'
}
- нотация в стиле карты
//adding x86 classifier will resolve only intel's (.so) lib
native_dependencies {
artifact group: 'com.snappydb', name: 'snappydb-native', version: '0.2+', classifier: 'x86'
}
//omit the classifier will resolve all supported architectures
native_dependencies {
artifact group: 'com.snappydb', name: 'snappydb-native', version: '0.2+'
}
В обоих обозначениях классификатор не обязателен. это означает, что, если он не указан , плагин пытается разрешить артефакты для всех архитектур: armeabi , armeabi-v7a , x86 и mips .
Вывод
Пока мы не получим полную поддержку NDK в плагине Android Gradle, использование android-native-dependencies может помочь вам создать свой CI и автоматизировать повторяющуюся задачу с нативными зависимостями. Пожалуйста, попробуйте и отправьте свой отзыв на @nabilhachicha .
Другой замечательный плагин Gradle, который я рекомендую — это android-sdk-manager ( Джейк Уортон ), который помогает загружать и управлять вашим Android SDK.