¿Cómo crear un tarro de biblioteca de Android con gradle sin revelar públicamente el código fuente?

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 comstackda 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.

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/ .

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 comstackr 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