How to use the legacy Apache HTTP client on Android Marshmallow?

93,258

Solution 1

Android Studio was complaining that org.apache.http classes like

org.apache.http.NameValuePair
org.apache.http.client.utils.URLEncodedUtils

were missing.

So I added org.apache.http.legacy.jar which is in Android/Sdk/platforms/android-23/optional folder to to app/libs

I also added this line to my app.gradle file

compile files('libs/org.apache.http.legacy.jar')

But if you're using more libraries, you can use this way

compile fileTree(dir: 'libs', include: ['*.jar'])

This resolved all my errors that were caused because google removed support of Apache HTTP client.

Solution 2

useLibrary 'org.apache.http.legacy' did not work for me until I upgraded the Gradle tools version in my main build.gradle file of my Android Studio project, as follows:

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

Solution 3

Perfect solution here by running a simple file path check. by running

   android {
    compileSdkVersion 'android-MNC'
    buildToolsVersion "23.0.0 rc3"
    useLibrary 'org.apache.http.legacy'

    defaultConfig {
        applicationId "com.example.user.androidmtest"
        minSdkVersion 'MNC'
        targetSdkVersion 'MNC'
        versionCode 1
        versionName "1.0"

    }

        getBootClasspath().each{File file ->
           println file.absolutePath
        }
    }
}

You will get something like below

/Users/"yourname"/Development/android-sdk-macosx/platforms/android-MNC/android.jar /Users/"yourname"/Development/android-sdk-macosx/platforms/android-MNC/optional/org.apache.http.legacy.jar

So there you go, the jar is there.For some reason it didn't get added to the project. but you can always add it manually I guess.

Solution 4

The answer above just helps the debug builds to run, and release builds that are utilizing gradle.

Insert this inside the application tag on the manifest file, on all project instances that uses the legacy apache classes:

<uses-library android:name="org.apache.http.legacy" android:required="false" />

This helps for those who are still using Eclipse and ant scripts during compile.

Solution 5

After many frustrating hours, the following worked:

1. Locate the apache jar. It should reside somewhere like:

C:\Users\<yourname>\AppData\Local\Android\sdk\platforms\android-23\optional

2. Copy org.apache.http.legacy.jar to your libs folder.

Either right click on libs -> paste , or use your file explorer to navigate to the libs folder of your project and paste.

If you don't have a libs folder, as I did, make a new project and import all relevant files into their respective places.

3. Click ok see this

4. Most important step: Right click on the apache folder and select Add As Library. see this

Hope this helps someone get on with their life.

Share:
93,258
android developer
Author by

android developer

Really like to develop Android apps &amp; libraries on my spare time. Github website: https://github.com/AndroidDeveloperLB/ My spare time apps: https://play.google.com/store/apps/developer?id=AndroidDeveloperLB

Updated on October 16, 2020

Comments

  • android developer
    android developer over 3 years

    Background

    On Android Marshmallow, Google has completely removed the support of Apache HTTP client (link here) because it doesn't have good performance compared to the alternatives.

    This might also be the cause for so many apps crashing on Android Marshmallow.

    The problem

    Google allows you to still use this API, just not as a built in one, by adding this line to the gradle file:

    useLibrary 'org.apache.http.legacy'
    

    So, this is what I did:

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

    And:

    android {
        compileSdkVersion 'android-MNC'
        buildToolsVersion "23.0.0 rc3"
        useLibrary 'org.apache.http.legacy'
    
        defaultConfig {
            applicationId "com.example.user.androidmtest"
            minSdkVersion 'MNC'
            targetSdkVersion 'MNC'
            versionCode 1
            versionName "1.0"
        }
    

    When I tried it, it compiled fine (no errors being shown, and I could run the proof-of-concept app, as it doesn't have any special code), but when I tried using some of the classes that I know that are part of the old API (like "HttpClient" class), I see that it doesn't allow me to do so.

    I know it's not recommended to use this solution, but we must have the app ready to work there at least temporarily, till we work 100% on all of the things that should change for Android Marshmallow, and we don't want surprises in the form of crashes.

    Here's a screenshot:

    enter image description here

    The question

    Why does it occur? Did I use it correctly?


    EDIT: reported about this issue here:

    https://code.google.com/p/android/issues/detail?id=181474

  • android developer
    android developer almost 9 years
    I don't understand. What is this code you've written? You mean I should search for this jar, and add it to the project. Please explain.
  • WenChao
    WenChao almost 9 years
    Yeah, you are right. I wrote that code in build.gradle under android clause. Exactly what I'm saying, the jar didn't get picked up automatically . Perhaps you need to add it manually
  • android developer
    android developer almost 9 years
    What does the code do? Is it really needed? Also, have you checked it? Does it work fine?
  • WenChao
    WenChao almost 9 years
    No,it just prints the file path. doesn't do anything fancy, you can remove it safely. That jar contains everything from the old apache jar(HttpClient,Log, etc.) I suppose it will work just fine.
  • android developer
    android developer almost 9 years
    ok, thank you. hope that I won't need it when the time comes. Will check it again if/when needed. For now, You get +1 for the effort.
  • Jürgen 'Kashban' Wahlmann
    Jürgen 'Kashban' Wahlmann almost 9 years
    Worked for me. I had to add the Jar as a library to my app module though, to get rid of the Android Studio errors about HttpClient and so forth.
  • ashughes
    ashughes almost 9 years
    I get Proguard issues when I include org.apache.http.legacy.jar: IOExcpetion: Can't write [path to classes.jar] (Can't read [path to libs/org.apache.http.legacy.jar(;;;;;;!META-INF/MANIFEST.MF)‌​] (Duplicate zip entry [org.apache.http.legacy.jar:org/apache/commons/codec/binary/‌​Hex.class])) Anyone else using Proguard? Any ideas?
  • android developer
    android developer almost 9 years
    I've now got back to this issue. Now I get this error when trying to use the jar: Error:Execution failed for task ':app:packageAllSyncmeappDebugClassesForMultiDex'. > java.util.zip.ZipException: duplicate entry: org/apache/http/ConnectionClosedException.class .Did you also have this issue?
  • Sheraz Ahmad Khilji
    Sheraz Ahmad Khilji almost 9 years
    This should be marked as Right Answer. It worked for me.
  • sandrstar
    sandrstar over 8 years
    @ashughes probably you get proguard issues because other libs e.g. commons-codec in some of your modules.
  • suitianshi
    suitianshi over 8 years
    what if I set android:targetSdkLevel to 22 or lower? Will my app crash on Android M?
  • android developer
    android developer over 8 years
    I also use httpcore-4.3.1.jar and httpmime-4.3.2.jar , so adding the legacy jar file causes other issues (like: Error:(5, 43) error: package org.apache.http.entity.mime.content does not exist ) , and if I don't remove them, I get errors that say that the classes already exist (same package name and class name). BTW, I think this already use the jar file : compile fileTree(dir: 'libs', include: ['*.jar'])
  • Nak Android Dev
    Nak Android Dev over 8 years
    @androiddeveloper I am also having same issue of multiple dex as i am using both jars you mentioned above. So did you find any solution for this?
  • Shirane85
    Shirane85 over 8 years
    Thanks a lot! any idea why only this change solve the issue?
  • android developer
    android developer over 8 years
    @NakAndroidDev Sadly no, and the team manager said we will move to okHttp to avoid those issues once and for all. I wonder how good it is.
  • Jamie Hall
    Jamie Hall over 8 years
    Apparently the useLibrary directive was only added to Gradle fairly recently, so need to use a newer version as I stated above.
  • Ricardo
    Ricardo over 8 years
    @CoPLaS what about eclipse, where can I find this lib?
  • android developer
    android developer over 8 years
    @NakAndroidDev Did you solve it ? I've now tried to do it again, and now I got: Error:Execution failed for task ':app:packageAllSyncmeappDebugClassesForMultiDex'. > java.util.zip.ZipException: duplicate entry: org/apache/http/ConnectionClosedException.class
  • Nak Android Dev
    Nak Android Dev over 8 years
    yes; but it's not proper fix yet. I think its bug with Android Studio. What i did is added useLibrary 'org.apache.http.legacy' in my gradle file and then tried to build run the app. it worked as it should. But when I open my class file and write its code then it's showing me error that can not resolve all these packages and classes. but on compile time and execution its not showing any error,
  • William
    William over 8 years
    It is very sad that Google has chosen to use a hack requiring people to add a binary to their project rather than publishing http-legacy to an artefact repo. I thought we had left that anti-pattern behind 10 years ago.
  • Sagar Devanga
    Sagar Devanga over 8 years
    I have this in the main gradle file : classpath 'com.android.tools.build:gradle:1.0.0-rc2' So should I remove this and add your line or keep both the lines and it would work without any problem
  • Jamie Hall
    Jamie Hall over 8 years
    Remove that and add the above.
  • Admin
    Admin over 8 years
    Thanks Works ! I think that Google will need repair this problem.
  • Krishna
    Krishna over 8 years
    Thanks. But When I'm using this now, all the basic classes and methods like HttpPost, HttpClient, NameValuePair, BasicNameValuePair are deprecated. Now What
  • KawaiKx
    KawaiKx about 8 years
    this is not silly... this is the answer that worked in my case... Past 36 hours I spent trying everything on earth, except this.. It sound silly in the beginning so I didn't take it seriously..
  • KawaiKx
    KawaiKx about 8 years
    Guys, try this out too... It really worked for me, where everything else failed
  • Arpit Patel
    Arpit Patel about 8 years
    it's my pleasure.@KawaiKx
  • activity
    activity almost 8 years
    You are Genius, Sir.
  • Leo supports Monica Cellio
    Leo supports Monica Cellio over 7 years
    Then just upvote CoPLaS answer instead of reproducing it here!
  • Lakshmi Narayanan
    Lakshmi Narayanan over 7 years
    It still hasn't worked for me even after this. Any possible diagnosis please @CoPLaS