Comment créer une bibliothèque Android avec Android Studio et gradle?

144

J'essaye de migrer un projet d'Eclipse mais rien de ce que j'ai essayé ne fonctionne. Dans Eclipse, j'ai 3 projets (2 projets d'application Android et 1 projet de bibliothèque Android). Les 2 projets d'application dépendent du projet de bibliothèque. Quand je fais l'exportation gradle, j'obtiens 3 projets qui ne fonctionnent pas. Je suis ouvert à la restructuration du projet mais je n'ai trouvé aucune documentation sur la façon dont cela devrait être fait.

Existe-t-il un moyen de faire fonctionner ensemble les 3 projets exportés par Eclipse? Est-ce que je ferais mieux de restructurer les choses et, dans l'affirmative, la documentation expliquant comment cela devrait être fait?

Mettre à jour

J'ai téléchargé l'intégralité du projet sur GitHub https://github.com/respectTheCode/android-studio-library-example

Mise à jour 1

Basé sur les suggestions de Padma Kumar, c'est ce que j'ai essayé.

  1. Créez un nouveau projet appelé MyApp
  2. Cliquez File > New Module, choisissez Android Libraryet nommez-leMyLib
  3. Cliquez sur Build > Make Project

La construction échoue avec cette erreur

Module "MyLib" was fully rebuilt due to project configuration/dependencies changes
Compilation completed with 1 error and 0 warnings in 19 sec
1 error
0 warnings
/.../MyApp/MyLib/build/bundles/debug/AndroidManifest.xml
Gradle: <manifest> does not have package attribute.

J'ai ensuite ajouté un packageattribut au manifeste en le faisant

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.mylib" >

Après la construction, j'obtiens cette erreur

Module "MyApp" was fully rebuilt due to project configuration/dependencies changes
Compilation completed with 2 errors and 0 warnings in 13 sec
2 errors
0 warnings
/.../MyApp/MyLib/src/main/java/com/example/mylib/MainActivity.java
Gradle: package R does not exist
Gradle: package R does not exist

L'ajout d'une dépendance ne semble pas avoir d'impact sur l'erreur. Continuant d'en haut

  1. Cliquez sur File > Project Structure > Modules > MyApp-MyApp
  2. Passer à l' Dependenciesonglet
  3. Cliquez + > Module Dependencyet choisissezMyLib
  4. Cliquez ApplyetOK
  5. Cliquez sur Build > Make Project

Mise à jour 2

Sur la base des suggestions d'Ethan, voici où nous obtenons

Les 2 sous-projets build.gradlesemblent avoir toutes les parties correctes et la seule différence est que la ligne de plugin ci-dessous est le MyApp/build.gradle.

buildscript {
    repositories {
        maven { url 'http://repo1.maven.org/maven2' }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.4'
    }
}
apply plugin: 'android'

dependencies {
    compile files('libs/android-support-v4.jar')
}

android {
    compileSdkVersion 17
    buildToolsVersion "17.0.0"

    defaultConfig {
        minSdkVersion 7
        targetSdkVersion 16
    }
}

Le projet racine build.gradleétait vide, j'ai donc ajouté les deux projets comme celui-ci

dependencies {
    compile project(":MyLib")
    compile project(":MyApp")
}

J'obtiens maintenant cette erreur lors de la construction

Gradle:
FAILURE: Build failed with an exception.
* Where:
Build file '/Users/kevin/GitHub/AppPress/MyApp/build.gradle' line: 2
* What went wrong:
A problem occurred evaluating root project 'MyApp'.
> Could not find method compile() for arguments [project ':MyLib'] on root project 'MyApp'.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

Mise à jour 3

Un grand merci Ethan pour avoir résolu cela.

  1. Ajouter compile project(':SubProjects:MyLib')auMyLib/build.gradle
  2. Retirer compile files('libs/android-support-v4.jar')duMyLib/build.gradle
  3. Fermer le projet et importer le projet racine à partir de gradle

Mise à jour 4

À partir de la version 0.1.2, vous pouvez désormais inclure compile "com.android.support:support-v4:13.0.0"au lieu de compile files('libs/android-support-v4.jar'). Comme il vient de mavin, vous pouvez désormais l'inclure dans plusieurs projets sans problème.

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:0.4.2'
    }
}

apply plugin: 'android'

dependencies {
    compile "com.android.support:support-v4:13.0.0"

    compile project(':SubProjects:MyLib')
}

Mise à jour 5

Depuis la version 0.1.3, il y a maintenant un bouton "Sync Project" dans la barre d'outils. Vous pouvez cliquer dessus au lieu de réimporter votre projet après avoir apporté des modifications aux .gradlefichiers.

respectTheCode
la source
J'ai fait une pull request pour votre projet github. Il y a eu 2 changements simples. Supprimez le contenu de votre /build.gradle. {J'ai fait cela parce que vous n'aviez pas défini de quel type de projet il s'agissait, alors il se plaignait de ne pas savoir quoi faire avec}, puis j'ai ajouté la dépendance de: SubProject: MyLib à: SubProject: MyApp. J'ai ensuite lancé ./gradlew: SubProject: MyApp: iD (iD maps to installDebug). J'ai également dû supprimer les libs / android-support-v4.jar en double. Comme ce n'est pas une «vraie» dépendance, vous ne pouvez pas l'avoir à deux endroits.
Ethan
J'ai commenté la pull request. github.com/respectTheCode/android-studio-library-example/pull/1
respectTheCode
1
Cela vaut la peine de mentionner que si vous ajoutez compile 'com.google.android:support-v4:r6'à chacun de vos projets et que le plugin maven (comme dans l'exemple build.gradle ci-dessous) au lieu du compile files('libs/android-support-v4.jar')gradle, vous vous rendrez compte que les deux projets incluent la même chose et ne l'incluront qu'une seule fois.
Ethan
@respectTheCode J'ai envoyé une pull request pour nettoyer un peu votre exemple de projet github. Merci d'avoir partagé!
JohnnyLambada
Possible duplication d' Android studio, gradle et NDK
Cameron Lowell Palmer

Réponses:

115

Note : Cette réponse est une réponse pur Gradle, j'utiliser dans IntelliJ sur une base régulière , mais je ne sais pas comment l'intégration est avec Android Studio. Je suis convaincu de savoir ce qui se passe pour moi, c'est ainsi que j'utilise Gradle et Android.

TL; DR Exemple complet - https://github.com/ethankhall/driving-time-tracker/

Avertissement : Il s'agit d'un projet sur lequel je travaille / travaillais.

Gradle a une défini structure (que vous pouvez changer, lien en bas vous indique comment) qui est très similaire à Maven si vous avez déjà utilisé.

Project Root
+-- src
|   +-- main (your project)
|   |   +-- java (where your java code goes)
|   |   +-- res  (where your res go)
|   |   +-- assets (where your assets go)
|   |   \-- AndroidManifest.xml
|   \-- instrumentTest (test project)
|       \-- java (where your java code goes)
+-- build.gradle
\-- settings.gradle

Si vous n'avez qu'un seul projet, le fichier settings.gradle n'est pas nécessaire. Cependant, vous souhaitez ajouter d'autres projets, nous en avons donc besoin.

Jetons maintenant un coup d'œil à ce fichier build.gradle. Vous allez en avoir besoin (pour ajouter les outils Android)

build.gradle

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.3'
    }
}

Nous devons maintenant parler à Gradle de certaines des parties Android. C'est assez simple. Un basique (qui fonctionne dans la plupart de mes cas) ressemble à ce qui suit. J'ai un commentaire dans ce bloc, il me permettra de spécifier le nom et le code de la version lors de la génération de l'APK.

build.gradle

apply plugin: "android"
android {
        compileSdkVersion 17
        /*
        defaultConfig {
            versionCode = 1
            versionName = "0.0.0"
        }
        */
    }

Quelque chose que nous allons vouloir ajouter, pour aider ceux qui n'ont pas encore vu la lumière de Gradle, un moyen pour eux d'utiliser le projet sans l'installer.

build.gradle

task wrapper(type: org.gradle.api.tasks.wrapper.Wrapper) {
    gradleVersion = '1.4'
}

Nous avons donc maintenant un projet à construire. Maintenant, nous allons ajouter les autres. Je les mets dans un répertoire, peut-être l'appeler deps, ou subProjects. Cela n'a pas vraiment d'importance, mais vous aurez besoin de savoir où vous le mettez. Pour indiquer à Gradle où se trouvent les projets, vous devrez les ajouter à settings.gradle.

Structure du répertoire:

Project Root
+-- src (see above)
+-- subProjects (where projects are held)
|   +-- reallyCoolProject1 (your first included project)
|       \-- See project structure for a normal app
|   \-- reallyCoolProject2 (your second included project)
|       \-- See project structure for a normal app
+-- build.gradle
\-- settings.gradle

settings.gradle:

include ':subProjects:reallyCoolProject1'
include ':subProjects:reallyCoolProject2'

La dernière chose dont vous devez vous assurer est que les subProjects / reallyCoolProject1 / build.gradle ont à la apply plugin: "android-library"place de apply plugin: "android".

Comme chaque projet Gradle (et Maven), nous devons maintenant informer le projet racine de sa dépendance. Cela peut également inclure toutes les dépendances Java normales souhaitées.

build.gradle

dependencies{
    compile 'com.fasterxml.jackson.core:jackson-core:2.1.4'
    compile 'com.fasterxml.jackson.core:jackson-databind:2.1.4'
    compile project(":subProjects:reallyCoolProject1")
    compile project(':subProjects:reallyCoolProject2')
}

Je sais que cela ressemble à beaucoup d'étapes, mais elles sont assez faciles une fois que vous le faites une ou deux fois. Cette méthode vous permettra également de construire sur un serveur CI en supposant que le SDK Android y soit installé.

NDK Side Note: Si vous comptez utiliser le NDK, vous aurez besoin de quelque chose comme ci-dessous. Un exemple de fichier build.gradle peut être trouvé ici: https://gist.github.com/khernyo/4226923

build.gradle

task copyNativeLibs(type: Copy) {
    from fileTree(dir: 'libs', include: '**/*.so' )  into  'build/native-libs'
}
tasks.withType(Compile) { compileTask -> compileTask.dependsOn copyNativeLibs }

clean.dependsOn 'cleanCopyNativeLibs'

tasks.withType(com.android.build.gradle.tasks.PackageApplication) { pkgTask ->
  pkgTask.jniDir new File('build/native-libs')
}

Sources:

  1. http://tools.android.com/tech-docs/new-build-system/user-guide
  2. https://gist.github.com/khernyo/4226923
  3. https://github.com/ethankhall/driving-time-tracker/
Ethan
la source
1
Merci @Ethan cela remplit certains des blancs. Android Studio ne manquait que le build.gradle du projet racine. Je mettrai à jour la question avec l'erreur que j'obtiens maintenant.
respectTheCode
1
J'ai essayé de cloner votre repo de suivi du temps de conduite et d'importer le projet, mais je ne suis pas compilé.
respectTheCode
J'ai oublié quelque chose, j'ai fait une nouvelle demande
Ethan
1
Salut @Ethan, il semble que vous soyez expérimenté avec Gradle, pourriez-vous aussi aider avec mon problème: stackoverflow.com/questions/17479076/…
TacB0sS
@Ethan Pouvez-vous aider avec un problème de dépendance avec Gradle pour Android s'il vous plaît?
JJD
6

Je viens d'avoir un problème très similaire avec les builds gradle / l'ajout de la bibliothèque .jar. Je l'ai fait fonctionner par une combinaison de:

  1. Déplacement du dossier libs jusqu'à la racine du projet (même répertoire que 'src'), et ajout de la bibliothèque à ce dossier dans finder (sous Mac OS X)
  2. Dans Android Studio, cliquez avec le bouton droit sur le dossier à ajouter en tant que bibliothèque
  3. Modification des dépendances dans le fichier build.gradle, ajout compile fileTree(dir: 'libs', include: '*.jar')}

MAIS plus important et plus ennuyeux, quelques heures seulement après l'avoir fait fonctionner, Android Studio vient de publier la version 0.3.7, qui prétend avoir résolu de nombreux problèmes tels que l'ajout de bibliothèques .jar

http://tools.android.com/recent

J'espère que cela aide les gens!

Joël Balmer
la source
1
Ce problème concerne les bibliothèques Andriod et non les bibliothèques Java .jar.
respectTheCode
2
Vrai! Cependant, mon problème concernait les builds gradle et le studio Android et cet article était suffisamment similaire pour m'avoir aidé à me diriger vers ma solution - je pensais juste que je répandrais la bonne nouvelle au cas où quelqu'un d'autre serait conduit à cette question, et était dans la même position moi.
Joel Balmer
1

Voici ma solution pour les utilisateurs de mac, je pense que cela fonctionne également pour Windows:

Accédez d'abord à votre barre d'outils Android Studio

Construire> Créer un projet (pendant que vous êtes en ligne, laissez-le télécharger les fichiers), puis

Build> Compile Module "le nom de votre application est affiché ici" (toujours en ligne, laissez les fichiers être
téléchargés et terminés), puis

Exécutez votre application qui est terminée, elle lancera votre émulateur et le configurera, puis l'exécutera!

C'est ça!!! Heureux les gars de codage !!!!!!!

Henula
la source
0

Gradle Build Tools 2.2.0+ - Tout fonctionne simplement

C'est la bonne façon de le faire

En essayant d'éviter l'expérimentation et franchement marre du NDK et de tout son piratage, je suis heureux que la version 2.2.x des Gradle Build Tools soit sortie et qu'elle fonctionne maintenant. La clé est externalNativeBuildet pointant ndkBuildargument de chemin à un Android.mkou changement ndkBuildà cmakeet pointer l'argument de chemin à un CMakeLists.txtscript de compilation.

android {
    compileSdkVersion 19
    buildToolsVersion "25.0.2"

    defaultConfig {
        minSdkVersion 19
        targetSdkVersion 19

        ndk {
            abiFilters 'armeabi', 'armeabi-v7a', 'x86'
        }

        externalNativeBuild {
            cmake {
                cppFlags '-std=c++11'
                arguments '-DANDROID_TOOLCHAIN=clang',
                        '-DANDROID_PLATFORM=android-19',
                        '-DANDROID_STL=gnustl_static',
                        '-DANDROID_ARM_NEON=TRUE',
                        '-DANDROID_CPP_FEATURES=exceptions rtti'
            }
        }
    }

    externalNativeBuild {
        cmake {
             path 'src/main/jni/CMakeLists.txt'
        }
        //ndkBuild {
        //   path 'src/main/jni/Android.mk'
        //}
    }
}

Pour plus de détails, consultez la page de Google sur l'ajout de code natif .

Une fois que cela est correctement configuré, vous pouvez ./gradlew installDebuget c'est parti. Vous devrez également être conscient que le NDK passe à clang puisque gcc est désormais obsolète dans le NDK Android.

Cameron Lowell Palmer
la source