Comment ajouter l'API HTTP Apache (héritée) en tant que dépendance au moment de la compilation à build.grade pour Android M?

96

Comme mentionné ici , Android M ne prend pas en charge l'API HTTP Apache. La documentation déclare:

utilisez plutôt la classe HttpURLConnection.

ou

Pour continuer à utiliser les API HTTP Apache, vous devez d'abord déclarer la dépendance de compilation suivante dans votre fichier build.gradle:

android {useLibrary 'org.apache.http.legacy'}

J'ai converti une grande partie de l'utilisation de HttpClient dans mon projet en HttpURLConnection, cependant, je dois toujours utiliser HttpClient dans quelques domaines. Par conséquent, j'essaie de déclarer 'org.apache.http.legacy' comme dépendance au moment de la compilation mais j'obtiens une erreur dans build.gradle:

Méthode Gradle DSL introuvable: 'useLibrary ()'

Ma question est la suivante: comment déclarer 'org.apache.http.legacy' comme dépendance à la compilation dans mon projet?

Toute aide est très appréciée. Merci

Virat Singh
la source
3
Assurez-vous que vous utilisez un plugin Gradle pour Android assez récent. Je suppose que c'est vraiment nouveau, ce qui signifie que vous auriez besoin de quelque chose comme 1.3.0-rc2. Vous pouvez également envisager d'utiliser la propre édition compatible Android d'Apache de HttpClient .
CommonsWare
Merci pour la réponse rapide @CommonsWare ... Faites-vous référence à la ligne "classpath 'com.android.tools.build:gradle:1.0.0'" dans le fichier build.gradle de niveau supérieur?
Virat Singh
1
Oui. Je serai plutôt surpris si 1.0.0a la useLibrarychose. Il est possible qu'elle se soit glissée avant la 1.3.x, vous pouvez donc essayer 1.2.3(AFAIK, la dernière version de production) et voir ce qui se passe.
CommonsWare
Je viens d'essayer '1.2.3' et pas de chance - même erreur -> "Méthode Gradle DSL introuvable: 'useLibrary ()'": /
Virat Singh
Ouais, puisque cela est lié à la M Developer Preview, je ne suis pas choqué par cela. Vous avez probablement besoin 1.3.0-rc2(ou quelque chose de plus récent, s'il y en a un).
CommonsWare

Réponses:

172

Pour l'API 23:

Build.gradle de niveau supérieur - /build.gradle

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

Build.gradle spécifique au module - /app/build.gradle

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.0"
    useLibrary 'org.apache.http.legacy'
    ...
}

Documents officiels (pour un aperçu cependant): http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-apache-http-client

Dernier changelog du plugin Android Gradle: http://tools.android.com/tech-docs/new-build-system

hidro
la source
2
Je mets à jour la version de construction de gradle, puis je déclare useLibrary pour apache également, mais j'obtiendrai également une erreur: Erreur: (204, 13) erreur: impossible de trouver la classe de symboles DefaultHttpClient Erreur: (204, 48) erreur: impossible de trouver la classe de symboles Erreur DefaultHttpClient: (205, 13) erreur: impossible de trouver la classe de symboles Erreur HttpPost: (205, 37) erreur: impossible de trouver la classe de symboles Erreur HttpPost: (207, 13) erreur: impossible de trouver la classe de symboles Erreur HttpResponse: (208, 13) erreur: impossible rechercher la classe de symboles Erreur HttpEntity: (209, 19) erreur: impossible de trouver la variable de symbole EntityUtils
Varnit Khandelwal
1
Quelque chose que j'ai manqué dans la réponse: vous devez vous assurer que le chemin de classe gradle se trouve dans le fichier de construction de niveau supérieur de votre application, où useLibrarydoit se trouver dans le fichier de construction spécifique à votre application.
Graeme
N'oubliez pas non plus d'ajouter ce fichier jar pour que la solution ci-dessus fonctionne :)
Sheraz Ahmad Khilji
@Sheraz qui n'est plus nécessaire - la version gradle le récupère automatiquement
Richard Le Mesurier
1
@Ratul, vous devriez ajouter un packagingOptions {}bloc à l'intérieur du androidbloc, à l'intérieur de ce bloc, ajouter exclude 'META-INF/LICENSE'... (chaque ligne par fichier en double signalé)
hidro
28

Une autre alternative consiste simplement à ajouter une dépendance jbundle. Ceci est plus convivial pour Android Studio car Android Studio ne donne pas le message "Impossible de résoudre le symbole ..."

 dependencies {
    compile 'org.jbundle.util.osgi.wrapped:org.jbundle.util.osgi.wrapped.org.apache.http.client:4.1.2'
 }
nexDev
la source
il est disponible sur le référentiel mavenCentral ().
nexDev
Il ne peut pas être compilé: Erreur: L'exécution a échoué pour la tâche ': <Proj>: package <Proj> Debug'. > Impossible de calculer le hachage de /Users/<user>/Documents/<Proj>/<Activity>/build/intermediates/classes-proguard/<Proj>/debug/classes.jar
Yuriy Chernyshov
avez-vous essayé de compiler (reconstruire) sans proguard?
nexDev
pouvez-vous s'il vous plaît montrer un exemple de projet qui fonctionne avec cela? Maintenant, j'obtiens cette erreur: Erreur: l'exécution a échoué pour la tâche ': app: packageAllSyncmeappDebugClassesForMultiDex'. > java.util.zip.ZipException: entrée en double: org / apache / http / annotation / GuardedBy.class
développeur Android
Eh bien, le type d'erreur que vous avez semble spécifique à votre projet. Vous avez des packages Apache en double. Un apparemment dans le org.jbundle. .... et l'autre quelque part dans l'une de vos bibliothèques. Je chercherais le package en double dans:
nexDev
13

Dans votre fichier build.gradle, ajoutez useLibrary 'org.apache.http.legacy' selon Android 6.0 Changes> Apache HTTP Client Removalnotes.

android {
    ...
    useLibrary 'org.apache.http.legacy'
    ...
}

Pour éviter les erreurs de lien manquantes, ajoutez aux dépendances

dependencies {
    provided 'org.jbundle.util.osgi.wrapped:org.jbundle.util.osgi.wrapped.org.apache.http.client:4.1.2'
}

en utilisant 'fourni', la dépendance ne sera pas incluse dans l'apk

lrampazzo
la source
11

Fichier juste copié: org.apache.http.legacy.jardu Android/Sdk/platforms/android-23/optionaldossier au dossier du projetapp/libs .

A fonctionné comme un charme pour 23.1.1.

CodeBulls Inc.
la source
2

J'ai résolu ce problème comme suit:

1.) Définissez le chemin de classe dans le fichier de construction de niveau supérieur comme indiqué par GUG:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.3.0-beta2'
    }
    allprojects {
        repositories {
           jcenter()
        }
    }
}

2.) Dans le fichier de construction d'un module spécifique:

android {
   useLibrary 'org.apache.http.legacy'
   compileSdkVersion 'android-MNC'
   buildToolsVersion '23.0.0 rc3'
}
UN D
la source
2

Comme les réponses sont un peu anciennes, je vais mettre ma solution (ce qui a fonctionné pour moi), cela peut être utile pour quelqu'un d'autre ... j'ai pris ma solution de la documentation officielle d'Apache, pas de contournement.

1 / en gradle:

dependencies {
...
// This is the maintained version from apache.
compile group: 'cz.msebera.android', name: 'httpclient', version: '4.4.1.1'
}

2 / dans le reste de l'application remplacez le org.apache.httppar cz.msebera.android.httpclientet toutes vos importations (dépendances) seront corrigées. vous pouvez simplement faire ctrl + shift + R et le remplacer dans tout le projet.

ahmed_khan_89
la source
2

cela devrait aider:

android {
    ...
    useLibrary 'org.apache.http.legacy'
    ...
}

Pour éviter les erreurs de lien manquantes, ajoutez aux dépendances

dependencies {
    provided 'org.jbundle.util.osgi.wrapped:org.jbundle.util.osgi.wrapped.org.apache.http.client:4.1.2'
}

ou

dependencies {
    compileOnly 'org.jbundle.util.osgi.wrapped:org.jbundle.util.osgi.wrapped.org.apache.http.client:4.1.2'
}

car

Warning: Configuration 'provided' is obsolete and has been replaced with 'compileOnly'.
Logeshwaran
la source
ou donner compiler au lieu de fourni les deux sera le travail
logeshwaran
avec la configuration ci-dessus, j'ai rencontré une erreur: (155, 0) Méthode Gradle DSL introuvable: 'provided ()'
RoFF
1

FWIW, la suppression de la bibliothèque Apache a été annoncée il y a quelque temps. Notre bon ami Jesse Wilson nous a donné un indice en 2011: http://android-developers.blogspot.com/2011/09/androids-http-clients.html

Google a cessé de travailler sur ApacheHTTPClient il y a quelque temps, donc toute bibliothèque qui en dépend encore doit être mise dans la liste des bibliothèques obsolètes à moins que les responsables ne mettent à jour leur code.

<rant> Je ne peux pas vous dire combien d'arguments techniques j'ai eu avec des personnes qui ont insisté pour rester avec le client HTTP Apache. Il y a quelques applications majeures qui vont s'arrêter parce que la direction de mes anciens employeurs qui ne doivent pas être nommés n'a pas écouté leurs meilleurs ingénieurs ou ne savait pas de quoi ils parlaient quand ils ont ignoré l'avertissement ... mais, l'eau sous le pont.

Je gagne.

</rant>

Codeur Roadie
la source
1
Je crois comprendre que Apache HttpClient est caché dans Android-23 mais n'est pas réellement supprimé. La suppression briserait de nombreux clients existants ciblant des plates-formes antérieures, où HttpClient n'est pas masqué, et ces applications existantes devraient toujours fonctionner sur Android-23. Sur Android-23, l'ajout de useLibrary sert à ajouter ces classes héritées au chemin de classe de démarrage, c'est-à-dire à la liste des classes fournies par la plateforme. Cela affiche essentiellement les classes sur Android-23.
Joe Bowbeer
Lorsqu'une classe est obsolète, il est courant de la masquer d'abord pour éviter qu'elle ne soit utilisée à l'avenir. Ensuite, il peut être supprimé au fil du temps. Quelque chose comme: 1. marquer comme obsolète dans la version actuelle. 2. cachez-vous dans la deuxième version. 3. refactorisez tout le code pour éliminer complètement l'ancienne classe.
Coder Roadie
0

Pour résoudre les problèmes, assurez-vous que vous utilisez la version des outils de génération "23.0.0 rc2" avec les outils suivants pour créer une dépendance gradle:

classpath 'com.android.tools.build:gradle:1.3.0-beta2'
GUG
la source