Je voudrais créer un Jar à partir d'un projet de bibliothèque Android. Il est configuré de la manière suivante:
ProjectName
\- lib
| \- lib
| \- armeabi
| \- libNativeFirst.so
| \- libNativeSecond.so
\- src
\- main
\- Java
\- com.package.sdk
\- PackageSDK.Java
Je voudrais que tout cela soit emballé dans un pot, mais sans révéler le code source présent dans PackageSDK.Java
.
J'ai configuré mon fichier build.gradle
Comme suit:
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
}
Lorsque j'exécute gradlew clean jar
Dans le répertoire du projet, un fichier Jar est créé dans ProjectName\build\libs
Appelé ProjectName.jar
. Sa structure est la suivante:
ProjectName.jar
\- lib
| \- armeabi
| \- libNativeFirst.so
| \- libNativeSecond.so
\- com
\- package
\- sdk
\- PackageSDK.Java
Je voudrais que le PackageSDK.class
Compilé soit inclus à la place du fichier PackageSDK.Java
Lors de l'exécution de la tâche jar
. Que puis-je changer pour y parvenir?
Selon la suggestion de Ben Manes, j'ai changé la configuration du sourceSets
comme suit:
sourceSets {
main {
Java {
srcDir 'src/main/Java'
}
resources {
srcDir 'src/../lib'
}
output {
classesDir 'build/classes'
resourcesDir 'build/javaResources'
}
}
}
Et la tâche jar
comme suit:
task jar(type: Jar) {
from Android.sourceSets.main.output
}
Gradle me donne maintenant cette sortie:
Could not find method output() for arguments [build_25r1m0a3etn5cudtt5odlegprd$_run_closure2_closure9_closure10_closure13@138532dc] on source set main.
Remarque: La réponse a été modifiée. Veuillez consulter la mise à jour du 28/07/2014 ci-dessous.
Voici une solution que j'ai trouvée. Il y a peut-être un meilleur moyen disponible, mais je ne l'ai pas encore trouvé.
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)
Fonctionnement gradlew makeJar
crée un ProjectName.jar
dans le build/libs
répertoire. La structure de ce pot est la suivante:
ProjectName.jar
\- lib
| \- armeabi
| \- libNativeFirst.so
| \- libNativeSecond.so
\- com
\- package
\- sdk
\- PackageSDK.class
C'est le résultat exact dont j'avais besoin. Je peux maintenant utiliser ProjectName.jar
avec succès dans d'autres projets.
EDIT: Bien que je puisse utiliser le pot résultant dans des projets au sein de Android Studio, je ne peux pas le faire dans des projets créés dans ADT en raison d'un avertissement concernant le code natif présent dans un fichier jar. il existe un indicateur pour désactiver cette vérification dans les paramètres, mais il ne fonctionne pas correctement. Ainsi, si vous voulez créer une bibliothèque qui utilise du code natif, ceux qui utilisent ADT devront copier manuellement le répertoire armeabi dans libs /.
Depuis Android Studio 0.8.0, les répertoires de sortie Gradle ont été modifiés et la configuration décrite ci-dessus ne fonctionnera pas. J'ai modifié ma configuration comme suit:
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')
}
IMPORTANT: Veuillez noter que ProjectName.jar
sera désormais placé dans build/outputs/
et PAS dans build/libs/
.
Juste pour ajouter une légère alternative à la réponse de @ BVB (bien que fortement basée sur elle), voici ce que je devais faire pour sortir un pot myapp-api.jar
qui était pour un Java seul projet qui traitait de l'interaction avec l'API de repos. Cela dépend d'Android.jar d'où la nécessité d'utiliser apply plugin: 'com.Android.application'
plutôt que simplement apply plugin: 'Java'
Appeler ./gradlew build jar
à partir du projet myJavaAPIP pour générer et générer le .jar vers 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's 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"
/>