Wie füge ich die Apache HTTP API (Legacy) als Abhängigkeit zur Kompilierungszeit zu build.grade für Android M hinzu?

96

Wie hier erwähnt , unterstützt Android M die Apache HTTP-API nicht. In den Dokumenten heißt es:

Verwenden Sie stattdessen die Klasse HttpURLConnection.

oder

Um die Apache-HTTP-APIs weiterhin verwenden zu können, müssen Sie zunächst die folgende Abhängigkeit zur Kompilierungszeit in Ihrer build.gradle-Datei deklarieren:

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

Ich habe einen Großteil der Verwendung von HttpClient in meinem Projekt in HttpURLConnection konvertiert, muss den HttpClient jedoch in einigen Bereichen noch verwenden. Daher versuche ich, 'org.apache.http.legacy' als Abhängigkeit zur Kompilierungszeit zu deklarieren, erhalte jedoch einen Fehler in build.gradle:

Gradle DSL-Methode nicht gefunden: 'useLibrary ()'

Meine Frage lautet: Wie deklariere ich 'org.apache.http.legacy' als Abhängigkeit zur Kompilierungszeit in meinem Projekt?

Jede Hilfe wird sehr geschätzt. Vielen Dank

Virat Singh
quelle
3
Stellen Sie sicher, dass Sie ein relativ aktuelles Gradle für Android-Plugin verwenden. Ich vermute, dass dies wirklich neu ist, was bedeutet, dass Sie so etwas brauchen würden 1.3.0-rc2. Sie können auch die Apache-eigene Android-kompatible Edition von HttpClient verwenden .
CommonsWare
Vielen Dank für die schnelle Antwort @CommonsWare ... Beziehen Sie sich auf die Zeile "classpath 'com.android.tools.build:gradle:1.0.0'" in der build.gradle-Datei der obersten Ebene?
Virat Singh
1
Ja. Ich werde ziemlich überrascht sein, wenn 1.0.0das useLibraryDing hat. Es ist möglich, dass es sich vor 1.3.x eingeschlichen hat, sodass Sie versuchen können 1.2.3(AFAIK, die neueste Produktionsversion) und sehen können, was passiert.
CommonsWare
Ich habe gerade '1.2.3' ausprobiert und kein Glück - gleicher Fehler -> "Gradle DSL-Methode nicht gefunden: 'useLibrary ()'": /
Virat Singh
Ja, da dies an die M Developer Preview gebunden ist, bin ich davon nicht schockiert. Wahrscheinlich brauchen Sie 1.3.0-rc2(oder etwas Neueres, wenn es eines gibt).
CommonsWare

Antworten:

172

Für API 23:

Top level build.gradle - /build.gradle

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

Modulspezifisches build.gradle - /app/build.gradle

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

Offizielle Dokumente (zur Vorschau): http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-apache-http-client

Neuestes Änderungsprotokoll für Android Gradle Plugins: http://tools.android.com/tech-docs/new-build-system

Hidro
quelle
2
Ich aktualisiere die Gradle-Build-Version und deklariere dann auch useLibrary für Apache, aber dann erhalte ich auch folgende Fehlermeldung: Fehler: (204, 13) Fehler: Symbolklasse kann nicht gefunden werden DefaultHttpClient Fehler: (204, 48) Fehler: Symbolklasse kann nicht gefunden DefaultHttpClient Fehler: (205, 13) Fehler: Symbolklasse kann nicht gefunden werden HttpPost Fehler: (205, 37) Fehler: Symbolklasse kann nicht gefunden HttpPost Fehler: (207, 13) Fehler: Symbolklasse kann nicht gefunden werden HttpResponse Fehler: (208, 13) Fehler: Kann nicht Symbolklasse finden HttpEntity Fehler: (209, 19) Fehler: Symbolvariable EntityUtils
Varnit Khandelwal
1
Etwas, das ich in der Antwort übersehen habe: Sie müssen sicherstellen, dass sich der Gradle-Klassenpfad in der Build-Datei der obersten Ebene Ihrer Apps befindet, wobei sich der Pfad useLibraryin Ihrer app-spezifischen Build-Datei befinden muss.
Graeme
Vergessen Sie auch nicht, diese JAR- Datei hinzuzufügen , damit die oben genannte Lösung funktioniert :)
Sheraz Ahmad Khilji
@Sheraz, das nicht mehr benötigt wird - der Gradle Build nimmt es automatisch auf
Richard Le Mesurier
1
@Ratul Sie sollten einen packagingOptions {}Block innerhalb des androidBlocks hinzufügen , innerhalb dieses Blocks hinzufügen exclude 'META-INF/LICENSE'... (jede Zeile pro duplizierte Datei gemeldet)
hidro
28

Eine andere Alternative besteht darin, nur die jbundle-Abhängigkeit hinzuzufügen. Dies ist Android Studio-freundlicher, da Android Studio nicht die Meldung "Symbol kann nicht aufgelöst werden ..." anzeigt.

 dependencies {
    compile 'org.jbundle.util.osgi.wrapped:org.jbundle.util.osgi.wrapped.org.apache.http.client:4.1.2'
 }
nexDev
quelle
Es ist im Repository von mavenCentral () verfügbar.
NexDev
Es kann nicht kompiliert werden: Fehler: Ausführung für Task ': <Proj>: Paket <Proj> Debug' fehlgeschlagen. > Hash von /Users/<user>/Documents/<Proj>/<Activity>/build/intermediates/classes-proguard/<Proj>/debug/classes.jar kann nicht berechnet werden
Yuriy Chernyshov
Haben Sie versucht, ohne Proguard zu kompilieren (neu zu erstellen)?
NexDev
Können Sie bitte ein Beispielprojekt zeigen, das damit funktioniert? Jetzt wird folgende Fehlermeldung angezeigt: Fehler: Ausführung für Task ': app: packageAllSyncmeappDebugClassesForMultiDex' fehlgeschlagen. > java.util.zip.ZipException: doppelter Eintrag: org / apache / http / annotation / GuardedBy.class
Android-Entwickler
Nun, die Art des Fehlers, den Sie haben, scheint spezifisch für Ihr Projekt zu sein. Sie haben doppelte Apache-Pakete. Eine anscheinend im org.jbundle. .... und der andere irgendwo in einer Ihrer Bibliotheken. Ich würde nach dem doppelten Paket suchen in:
nexDev
13

Fügen Sie in Ihrer build.gradle-Datei useLibrary 'org.apache.http.legacy' gemäß Android 6.0 Changes> Apache HTTP Client Removalnotes hinzu.

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

Um fehlende Linkfehler zu vermeiden, fügen Sie Abhängigkeiten hinzu

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

mit 'vorausgesetzt' wird die abhängigkeit nicht in die apk aufgenommen

lrampazzo
quelle
11

Einfach kopierte Datei: org.apache.http.legacy.jarvon Android/Sdk/platforms/android-23/optionalOrdner in Projektordner app/libs.

Hat wie ein Zauber für 23.1.1 funktioniert.

CodeBulls Inc.
quelle
2

Ich habe dieses Problem folgendermaßen gelöst:

1.) Legen Sie den Klassenpfad in der Build-Datei der obersten Ebene wie in der GUG angegeben fest:

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

2.) In der Build-Datei eines bestimmten Moduls:

android {
   useLibrary 'org.apache.http.legacy'
   compileSdkVersion 'android-MNC'
   buildToolsVersion '23.0.0 rc3'
}
ANZEIGE
quelle
2

Da die Antworten etwas alt sind, werde ich meine Lösung (was für mich funktioniert hat) einfügen, es kann für jemand anderen hilfreich sein ... Ich habe meine Lösung aus der offiziellen Dokumentation von Apache entnommen, keine Umgehung.

1 / in Gradle:

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

2 / im Rest der App ersetzen Sie das org.apache.httpdurch cz.msebera.android.httpclientund alle Ihre Importe (Abhängigkeiten) werden behoben. Sie können einfach Strg + Umschalt + R drücken und es im gesamten Projekt ersetzen.

ahmed_khan_89
quelle
2

es sollte helfen:

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

Um fehlende Linkfehler zu vermeiden, fügen Sie Abhängigkeiten hinzu

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

oder

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

weil

Warning: Configuration 'provided' is obsolete and has been replaced with 'compileOnly'.
Logeshwaran
quelle
oder geben Sie kompilieren statt vorausgesetzt, beide werden funktionieren
logeshwaran
Mit der obigen Konfiguration traf ich auf Fehler: (155, 0) Gradle DSL-Methode nicht gefunden: 'vorausgesetzt ()'
RoFF
1

FWIW das Entfernen der Apache-Bibliothek wurde vor einiger Zeit vorhergesagt. Unser guter Freund Jesse Wilson gab uns 2011 einen Hinweis: http://android-developers.blogspot.com/2011/09/androids-http-clients.html

Google hat vor einiger Zeit die Arbeit an ApacheHTTPClient eingestellt. Daher sollte jede Bibliothek, die sich noch darauf verlässt, in die Liste der veralteten Bibliotheken aufgenommen werden, es sei denn, die Betreuer aktualisieren ihren Code.

<rant> Ich kann Ihnen nicht sagen, wie viele technische Argumente ich mit Leuten hatte, die darauf bestanden, beim Apache HTTP-Client zu bleiben. Es gibt einige wichtige Apps, die kaputt gehen werden, weil das Management meiner nicht zu nennenden früheren Arbeitgeber nicht auf ihre Top-Ingenieure gehört hat oder wusste, wovon sie sprachen, als sie die Warnung ignorierten ... aber Wasser unter die Brücke.

Ich gewinne.

</rant>

Coder Roadie
quelle
1
Mein Verständnis ist, dass der Apache HttpClient in Android-23 versteckt ist, aber nicht tatsächlich entfernt wird. Durch das Entfernen würden viele vorhandene Clients beschädigt, die auf frühere Plattformen abzielen, auf denen HttpClient nicht verborgen ist, und es wird erwartet, dass diese vorhandenen Apps weiterhin auf Android-23 ausgeführt werden. Unter Android-23 dient das Hinzufügen von useLibrary dazu, diese älteren Klassen an den Boot-Klassenpfad anzuhängen, dh an die Liste der Klassen, die von der Plattform bereitgestellt werden. Dies macht die Klassen auf Android-23 im Wesentlichen frei.
Joe Bowbeer
Wenn eine Klasse veraltet ist, ist es üblich, sie zuerst auszublenden, um zu verhindern, dass sie in Zukunft verwendet wird. Dann kann es im Laufe der Zeit entfernt werden. So etwas wie: 1. In der aktuellen Version als veraltet markieren. 2. Verstecke dich in der zweiten Version. 3. Refaktorieren Sie den gesamten Code, um die alte Klasse vollständig zu entfernen.
Coder Roadie
0

Um die Probleme zu beheben, stellen Sie sicher, dass Sie die Build-Tools-Version "23.0.0 rc2" mit den folgenden Tools verwenden, um die Gradle-Abhängigkeit zu erstellen:

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