Как создать баннер библиотеки Android с помощью gradle без публичного раскрытия исходного кода?
Я хотел бы создать Jar из проекта библиотеки Android. Он настраивается следующим образом:
ProjectName
\- lib
| \- lib
| \- armeabi
| \- libNativeFirst.so
| \- libNativeSecond.so
\- src
\- main
\- java
\- com.package.sdk
\- PackageSDK.java
Я бы хотел, чтобы все это было упаковано в Jar, но не обнаружило исходный код, присутствующий в PackageSDK.java
.
Я установил свой файл build.gradle
следующим образом:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.5.+'
}
}
apply plugin: 'android-library'
repositories {
mavenCentral()
}
android {
compileSdkVersion 18
buildToolsVersion "18.0.1"
defaultConfig {
minSdkVersion 10
targetSdkVersion 18
}
sourceSets {
main {
java {
srcDir 'src/main/java'
}
resources {
srcDir 'src/../lib'
}
}
}
}
task jar(type: Jar) {
from android.sourceSets.main.allSource
}
Когда я запускаю gradlew clean jar
в каталоге проекта, файл Jar создается в ProjectName\build\libs
, называемом ProjectName.jar
. Его структура выглядит следующим образом:
ProjectName.jar
\- lib
| \- armeabi
| \- libNativeFirst.so
| \- libNativeSecond.so
\- com
\- package
\- sdk
\- PackageSDK.java
Я хотел бы, чтобы скомпилированный PackageSDK.class
был включен вместо файла PackageSDK.java
при выполнении задачи jar
. Что я могу изменить для достижения этого?
Изменить:
В предложении Бена Манеса я изменил конфигурацию sourceSets
на следующее:
sourceSets {
main {
java {
srcDir 'src/main/java'
}
resources {
srcDir 'src/../lib'
}
output {
classesDir 'build/classes'
resourcesDir 'build/javaResources'
}
}
}
И задача jar
:
task jar(type: Jar) {
from android.sourceSets.main.output
}
Gradle теперь дает мне этот результат:
Could not find method output() for arguments [build_25r1m0[email protected]138532dc] on source set main.
Ответы
Ответ 1
Примечание: Ответ отредактирован. См. Обновление от 07/28/2014 ниже.
Вот решение, с которым я столкнулся. Там может быть лучший способ, но я еще не нашел его.
android {
compileSdkVersion 18
buildToolsVersion "18.0.1"
defaultConfig {
minSdkVersion 10
targetSdkVersion 18
}
sourceSets {
main {
java {
srcDir 'src/main/java'
}
resources {
srcDir 'src/../lib'
}
}
}
}
task clearJar(type: Delete) {
delete 'build/libs/ProjectName.jar'
}
task makeJar(type: Copy) {
from('build/bundles/release/')
into('build/libs/')
include('classes.jar')
rename ('classes.jar', 'ProjectName.jar')
}
makeJar.dependsOn(clearJar, build)
Запуск gradlew makeJar
создает ProjectName.jar
в каталоге build/libs
. Структура этой банки следующая:
ProjectName.jar
\- lib
| \- armeabi
| \- libNativeFirst.so
| \- libNativeSecond.so
\- com
\- package
\- sdk
\- PackageSDK.class
Это точный результат, который мне нужен. Теперь я могу использовать ProjectName.jar
в других проектах.
EDIT: Хотя я могу использовать полученную банку в проектах в Android Studio, я не могу сделать этого в проектах, созданных в ADT, из-за предупреждения о том, что собственный код присутствует в файле jar. Предположительно, есть флажок, чтобы отключить эту проверку в настройках, но он работает неправильно. Таким образом, если вы хотите создать библиотеку, которая использует собственный код, те, кто использует ADT, должны будут вручную скопировать каталог armeabi в libs/.
28.07.2014 Обновление:
Начиная с Android Studio 0.8.0, Gradle были изменены каталоги вывода, и описанная выше конфигурация не будет работать. Я изменил свою конфигурацию на следующее:
task clearJar(type: Delete) {
delete 'build/outputs/ProjectName.jar'
}
task makeJar(type: Copy) {
from('build/intermediates/bundles/release/')
into('build/outputs/')
include('classes.jar')
rename ('classes.jar', 'ProjectName.jar')
}
ВАЖНО: Обратите внимание, что ProjectName.jar
теперь будет помещаться в build/outputs/
и NOT в build/libs/
.
Ответ 2
Просто чтобы добавить небольшую альтернативу @BVB-ответу (хотя и в значительной степени основанный на нем), здесь я должен был сделать вывод jar myapp-api.jar
, который был для проекта только на Java, который касался взаимодействия с API-интерфейсом. Это зависит от Android.jar, поэтому необходимо использовать apply plugin: 'com.android.application'
, а не только apply plugin: 'java'
Вызов ./gradlew build jar
из myJavaAPIProject для сборки и генерации .jar в myJavaAPIProject/build/libs/myapp-api.jar
build.gradle
//Even though this is a Java project, we need to apply the android plugin otherwise it cannot find the SDK/android.jar and so cannot compile
apply plugin: 'com.android.application'
dependencies {
//this ensures we have gson.jar and anything else in the /lib folder
compile fileTree(dir: 'lib', include: '*.jar')
}
repositories {
mavenCentral()
}
android{
compileSdkVersion 21
buildToolsVersion "21.0.1"
defaultConfig {
minSdkVersion 10
targetSdkVersion 21
}
sourceSets {
main {
java {
//points to an empty manifest, needed just to get the build to work
manifest.srcFile 'AndroidManifest.xml'
//defined our src dir as it not the default dir gradle looks for
java.srcDirs = ['src']
}
}
}
//enforce java 7
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
//Actually created the .jar file
task jar(type: Jar) {
//from android.sourceSets.main.java
from 'build/intermediates/classes/release/'
archiveName 'myapp-api.jar'
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- this is a dummy file needed to ensure gradle validates and builds ok -->
<manifest
package="com.myapp.android"
/>