script - gradle version android studio
¿Cómo crear un tarro de biblioteca de Android con gradle sin revelar públicamente el código fuente? (2)
Me gustaría crear un Jar de un proyecto de biblioteca de Android. Está configurado de la siguiente manera:
ProjectName
/- lib
| /- lib
| /- armeabi
| /- libNativeFirst.so
| /- libNativeSecond.so
/- src
/- main
/- java
/- com.package.sdk
/- PackageSDK.java
Me gustaría que todo esto se empaquete en un Jar, pero sin revelar el código fuente presente en PackageSDK.java
.
Configuré mi archivo build.gradle
así:
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
}
Cuando ejecuto gradlew clean jar
en el directorio del proyecto, se crea un archivo Jar en ProjectName/build/libs
llamado ProjectName.jar
. Su estructura es la siguiente:
ProjectName.jar
/- lib
| /- armeabi
| /- libNativeFirst.so
| /- libNativeSecond.so
/- com
/- package
/- sdk
/- PackageSDK.java
Me gustaría que se incluyera la PackageSDK.class
compilada en lugar del archivo PackageSDK.java
al ejecutar la tarea jar
. ¿Qué puedo cambiar para lograr esto?
Editar:
Según la sugerencia de Ben Manes, cambié la configuración de los sourceSets
de sourceSets
a lo siguiente:
sourceSets {
main {
java {
srcDir ''src/main/java''
}
resources {
srcDir ''src/../lib''
}
output {
classesDir ''build/classes''
resourcesDir ''build/javaResources''
}
}
}
Y la tarea jar
a lo siguiente:
task jar(type: Jar) {
from android.sourceSets.main.output
}
Gradle ahora me está dando esta salida:
Could not find method output() for arguments [build_25r1m0a3etn5cudtt5odlegprd$_run_closure2_closure9_closure10_closure13@138532dc] on source set main.
Solo para agregar una ligera alternativa a la respuesta de @ BVB (aunque está muy basada en ella) esto es lo que tuve que hacer para generar un jar myapp-api.jar
que fuera para un proyecto solo de Java que tratara la interacción de la API de reposo. Depende de Android.jar, por lo tanto, es necesario utilizar el apply plugin: ''com.android.application''
lugar de simplemente apply plugin: ''java''
Llamar a ./gradlew build jar
desde myJavaAPIProject para compilar y generar el .jar a 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"
/>
Nota: La respuesta ha sido editada. Por favor, consulte la actualización del 28/07/2014 a continuación.
Aquí hay una solución que terminé ideando. Puede haber una mejor manera disponible, pero aún no la he encontrado.
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)
Al ejecutar gradlew makeJar
crea un ProjectName.jar
en el directorio build/libs
. La estructura de este jar es la siguiente:
ProjectName.jar
/- lib
| /- armeabi
| /- libNativeFirst.so
| /- libNativeSecond.so
/- com
/- package
/- sdk
/- PackageSDK.class
Este es el resultado exacto que necesitaba. Ahora puedo usar ProjectName.jar
éxito en otros proyectos.
EDITAR: Aunque puedo usar el jar resultante en proyectos dentro de Android Studio, no puedo hacerlo en proyectos creados en ADT debido a una advertencia sobre la presencia de código nativo dentro de un archivo jar. Supuestamente hay una bandera para desactivar esta configuración de verificación, pero no funciona correctamente. Por lo tanto, si desea crear una biblioteca que use código nativo, aquellos que usan ADT deberán copiar manualmente el directorio armeabi en libs /.
28/07/2014 Actualización:
A partir de Android Studio 0.8.0, los directorios de salida de Gradle se han cambiado y la configuración descrita anteriormente no funcionará. Cambié mi configuración a lo siguiente:
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'')
}
IMPORTANTE: tenga en cuenta que ProjectName.jar
ahora se colocará en build/outputs/
y NO en build/libs/
.