web-dev-qa-db-fra.com

Comment créer un Android Pot de bibliothèque avec gradle sans révéler publiquement le code source?

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?

Modifier:

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.

35
BVB

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

Mise à jour du 28/07/2014:

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

69
BVB

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"
    />
8
scottyab