如何在 Android Marshmallow 上使用旧版 Apache HTTP 客户端?

Posted

技术标签:

【中文标题】如何在 Android Marshmallow 上使用旧版 Apache HTTP 客户端?【英文标题】:How to use the legacy Apache HTTP client on Android Marshmallow? 【发布时间】:2015-10-17 15:11:58 【问题描述】:

背景

android Marshmallow 上,Google 已经完全取消了对 Apache HTTP 客户端的支持(链接here),因为与替代品相比,它的性能并不好。

这也可能是许多应用在 Android Marshmallow 上崩溃的原因。

问题

Google 允许您仍然使用此 API,只是不作为内置 API,只需将此行添加到 gradle 文件:

useLibrary 'org.apache.http.legacy'

所以,这就是我所做的:

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

还有:

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"
    

当我尝试它时,它编译得很好(没有显示错误,并且我可以运行概念验证应用程序,因为它没有任何特殊代码),但是当我尝试使用一些类时我知道这是旧 API 的一部分(如“HttpClient”类),我发现它不允许我这样做。

我知道不建议使用此解决方案,但我们必须让应用程序准备好至少暂时在那里工作,直到我们 100% 处理所有应该为 Android Marshmallow 更改的事情,我们不希望崩溃形式的惊喜。

截图如下:

问题

为什么会发生?我正确使用了吗?


编辑:在这里报告了这个问题:

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

【问题讨论】:

编译得很好你的意思是 gradle 同步得很好,或者你在运行时得到一个 ClassNotFoundException 吗? 你能发一些android studioat的截图 @Blackbelt 我的意思是,在我编写应该支持的类之前,它可以编译并运行良好(因为没有什么可以使用它)。不可能有任何 ClassNotFoundException,因为我还没有使用它们。只有当我尝试使用应该存在的类时,我不能。它不允许我这样做,也没有为我提供所需的导入。 @user4847410 截图到底是什么?试图强行输入会导致它不被识别。并且使用那里存在的类也可以。无论如何,我已经更新了问题以显示当前情况,这是非常小的...... 检查您是否使用最新的 beta gradle。依赖项 classpath 'com.android.tools.build:gradle:1.3.0' 版本之后似乎缺少某些东西(即'-beta'或其他东西)。使用最新的测试版为我解决了这个问题 【参考方案1】:

Android Studio 抱怨 org.apache.http 类喜欢

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

失踪了。

所以我添加了org.apache.http.legacy.jar,它位于 Android/Sdk/platforms/android-23/optional 文件夹到 app/libs

我还将这一行添加到我的app.gradle 文件中

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

但是如果你使用更多的库,你可以这样使用

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

这解决了我所有的错误,因为谷歌删除了对 Apache HTTP 客户端的支持。

【讨论】:

为我工作。不过,我必须将 Jar 作为库添加到我的应用程序模块中,以消除有关 HttpClient 等的 Android Studio 错误。 我在包含 org.apache.http.legacy.jar 时遇到 Proguard 问题: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])) 还有其他人在使用 Proguard 吗?有什么想法吗? 很遗憾,Google 选择使用一种 hack,要求人们将二进制文件添加到他们的项目中,而不是将 http-legacy 发布到人工制品仓库。我以为我们在 10 年前就抛弃了这种反模式。 你是天才,先生。 即使在此之后它仍然没有为我工作。任何可能的诊断请@CoPLaS【参考方案2】:

useLibrary 'org.apache.http.legacy' 对我不起作用,直到我在我的 Android Studio 项目的主 bu​​ild.gradle 文件中升级了 Gradle 工具版本,如下所示:

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

【讨论】:

非常感谢!知道为什么只有这个更改才能解决问题吗? 显然 useLibrary 指令是最近才添加到 Gradle 中的,所以需要使用更新的版本,如上所述。 我在主 gradle 文件中有这个:classpath 'com.android.tools.build:gradle:1.0.0-rc2' 所以我应该删除这个并添加你的行还是保留这两个行和它会毫无问题地工作 删除并添加上述内容。【参考方案3】:

通过运行简单的文件路径检查来完美解决此问题。 通过运行

   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().eachFile file ->
           println file.absolutePath
        
    

你会得到类似下面的东西

/Users/"你的名字"/Development/android-sdk-macosx/platforms/android-MNC/android.jar /Users/"你的名字"/Development/android-sdk-macosx/platforms/android-MNC/optional/org.apache.http.legacy.jar

你去吧,罐子就在那里。由于某种原因,它没有被添加到项目中。但我猜你总是可以手动添加它。

【讨论】:

我不明白。你写的这段代码是什么?你的意思是我应该搜索这个 jar,并将其添加到项目中。请解释一下。 是的,你是对的。我在 android 子句下的 build.gradle 中编写了该代码。正是我所说的,罐子没有被自动捡起。也许您需要手动添加它 代码有什么作用?真的需要吗?另外,你检查了吗?它工作正常吗? 不,它只是打印文件路径。没有做任何花哨的事情,您可以安全地删除它。该 jar 包含旧 apache jar(HttpClient、Log 等)中的所有内容。我想它会工作得很好。 好的,谢谢。希望到时候我不需要它。如果/需要时会再次检查。目前,您的努力获得了 +1。【参考方案4】:

经过许多令人沮丧的时间后,以下方法奏效了:

1.找到 apache jar。 它应该位于以下位置:

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

2。复制 org.apache.http.legacy.jar 到您的 libs 文件夹。

右键单击 libs -> paste ,或使用文件资源管理器导航到项目的 libs 文件夹并粘贴。

如果您像我一样没有 libs 文件夹,请创建一个新项目并将所有相关文件导入各自的位置。

3.点击ok see this

4.最重要的一步:右键点击apache文件夹,选择Add As Library see this

希望这可以帮助人们继续他们的生活。

【讨论】:

【参考方案5】:

上面的答案只是帮助调试构建运行,并发布使用 gradle 的构建。

在清单文件的应用程序标签中插入这个,在所有使用旧 apache 类的项目实例上:

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

这对那些在编译期间仍在使用 Eclipse 和 ant 脚本的人有所帮助。

【讨论】:

【参考方案6】:

我知道这是一个愚蠢的理由,但在列表中尝试一下......

我最近遇到了这个问题,它是由路径长度限制引起的,我认为它最多 256 个字符。

重新定位您的项目,构建将成功。希望这对您有用。

【讨论】:

这并不傻......这是对我来说有效的答案......过去 36 小时,我花了 36 个小时尝试地球上的所有东西,除了这个......一开始听起来很傻,所以我没有不要当真.. 伙计们,也试试这个...它真的对我有用,其他一切都失败了 这是我的荣幸。@KawaiKx【参考方案7】:

位于

的旧版 Apache 库
[ANDROID_SDK]\platforms\android-23\optional\org.apache.http.legacy.jar 

所以你可以将它复制到你的项目 libs 或者只是使用

compile files("$android.getSdkDirectory().getAbsolutePath()" + File.separator + "platforms" + File.separator + "android-23" + File.separator + "optional" + File.separator + "org.apache.http.legacy.jar")

在你的 /app/build.gradle

【讨论】:

【参考方案8】:

首先你必须在你的 libs 文件夹中检查它

Then add into your gradle file like this 

    android 
        compileSdkVersion 23
        buildToolsVersion '23.0.2'

        defaultConfig 
            applicationId "info.tranetech.laundry"
            minSdkVersion 15
            targetSdkVersion 23
            versionCode 1
            versionName "1.0"
        
        buildTypes 
            release 
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            
        
    
    android 
        useLibrary 'org.apache.http.legacy'
    
    dependencies 
        compile fileTree(dir: 'libs', include: ['*.jar'])
        compile 'com.android.support:appcompat-v7:23.0.1
        compile 'com.android.support:design:23.0.1
        testCompile 'junit:junit:4.12'
        compile files('libs/android-async-http-1.4.4.jar')
        compile 'com.google.android.gms:play-services:8.4.0'
    

【讨论】:

【参考方案9】:

在 sdk/platforms/android-23/optional/optional.json 中启用它

[
  
    "name": "org.apache.http.legacy",
    "jar": "org.apache.http.legacy.jar",
    "manifest": false
  
]

【讨论】:

【参考方案10】:

删除

useLibrary 'org.apache.http.legacy' 

来自 build.gradle,我还将这一行添加到我的 app.gradle 文件中

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

但是如果你使用更多的库,你可以使用这种方式

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

CoPLaS 回答解决了我的问题。

【讨论】:

那么就给 CoPLaS 的答案投票,而不是在这里复制它!【参考方案11】:

如何在 Android Marshmallow 上使用旧版 Apache HTTP 客户端?

继续使用 API 23+ 的 Apache HTTP 类:

首先,一定要把gradle依赖加入build.gradlef

buildscript 

    dependencies 
        classpath 'com.android.tools.build:gradle:2.0.0'
    

然后在您的项目的build.gradle 中添加引用:

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

【讨论】:

【参考方案12】:

解决此问题的一个简单方法是 C:\Users\username\AppData\Local\Android\sdk\platforms。在这里删除您的 android-23 并从 SDK 管理器再次更新您的 API 23。它会解决你的问题。

【讨论】:

以上是关于如何在 Android Marshmallow 上使用旧版 Apache HTTP 客户端?的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式打开 Android 6.0 (Marshmallow) 上特定应用的权限屏幕?

如何在 Android Marshmallow 上使用旧版 Apache HTTP 客户端?

如何在 Android 6.0 Marshmallow 中访问相机?

如何在打盹模式下移动设备(Android Preview M / Marshmallow)?

Android Marshmallow:使用 Espresso 测试权限?

如何从 Android 版本 Marshmallow 开始请求从 Android 拨打电话的权限?