Android问题与Apache http客户端android库

时间:2017-09-21 07:55:19

标签: android apache-httpclient-4.x apache-commons-httpclient androidhttpclient vimeo-android

这是我正在使用的库: https://github.com/clickntap/Vimeo

我正在尝试将该库用于Android应用。我的测试设备是Kitkat(4.4.4)。

这是我的gradle配置:

compileSdkVersion 25
buildToolsVersion "25.0.3"
useLibrary  'org.apache.http.legacy'

defaultConfig {
    applicationId "my.app.package"
    minSdkVersion 16
    targetSdkVersion 25
    versionCode 1
    versionName "1.0.0-alpha"
}

以下是我添加库的方法:

compile 'com.clickntap:vimeo:1.10'

但我在Vimeo.addVideo()上收到以下错误:

java.lang.NoClassDefFoundError: org.apache.http.impl.client.HttpClientBuilder

和警告:

WARNING: Dependency org.apache.httpcomponents:httpclient:4.3.6 is ignored for debug as it may be conflicting with the internal version provided by Android.
WARNING: Dependency org.json:json:20140107 is ignored for debug as it may be conflicting with the internal version provided by Android.

所以我搜索了一下,发现我可以这样做:

compile 'org.apache.httpcomponents:httpclient-android:4.3.5.1'
compile('com.clickntap:vimeo:1.10') {
    exclude group: 'org.apache.httpcomponents'
    exclude group: 'org.json'
}

但是现在我仍然在Vimeo.addVideo()上收到此错误,但找不到任何解决方案:

java.lang.NoSuchMethodError: org.apache.http.entity.FileEntity.<init>

请帮助:(

谢谢,

P.S。 这是第一种情况的堆栈跟踪:

Caused by: java.lang.NoClassDefFoundError: org.apache.http.impl.client.HttpClientBuilder
                at com.clickntap.vimeo.Vimeo.apiRequest(Vimeo.java:218)
                at com.clickntap.vimeo.Vimeo.beginUploadVideo(Vimeo.java:122)
                at com.clickntap.vimeo.Vimeo.addVideo(Vimeo.java:138)
                at my.app.package.VimeoActivity$6.subscribe(VimeoActivity.java:163) // my activity
                at io.reactivex.internal.operators.single.SingleCreate.subscribeActual(SingleCreate.java:39)
                at io.reactivex.Single.subscribe(Single.java:2702)
                at io.reactivex.internal.operators.single.SingleSubscribeOn$SubscribeOnObserver.run(SingleSubscribeOn.java:89)
                at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:451)
                at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61)
                at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52) 
                at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
                at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152) 
                at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265) 
                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
                at java.lang.Thread.run(Thread.java:841) 

这是第二种情况,其中包括httpclient-android

Caused by: java.lang.NoSuchMethodError: org.apache.http.entity.FileEntity.<init>
                at com.clickntap.vimeo.Vimeo.apiRequest(Vimeo.java:247)
                at com.clickntap.vimeo.Vimeo.uploadVideo(Vimeo.java:126)
                at com.clickntap.vimeo.Vimeo.addVideo(Vimeo.java:140)
                at my.app.package.VimeoActivity$6.subscribe(VimeoActivity.java:163) // my activity
                at io.reactivex.internal.operators.single.SingleCreate.subscribeActual(SingleCreate.java:39)
                at io.reactivex.Single.subscribe(Single.java:2702)
                at io.reactivex.internal.operators.single.SingleSubscribeOn$SubscribeOnObserver.run(SingleSubscribeOn.java:89)
                at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:451)
                at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61)
                at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52) 
                at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
                at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152) 
                at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265) 
                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
                at java.lang.Thread.run(Thread.java:841) 

1 个答案:

答案 0 :(得分:2)

Android版&lt; 6嵌入了Apache HTTP Client 4.0.beta快照(https://hc.apache.org/httpcomponents-client-4.3.x/android-port.html)的分支。

第一种情况失败,因为在httpclient:4.3。

上引入了HttpClientBuilder

第二种情况失败是因为您正在使用加载旧版httpclient库的useLibrary 'org.apache.http.legacy'compile 'org.apache.httpcomponents:httpclient-android:4.3.5.1'。 Vimeo客户端使用遗留库中不存在的FileEntity构造函数,该构造函数存在于类路径中,并优先于FileEntity类的httpclient-android版本。

我建议像第二种情况一样使用依赖项,但删除useLibrary 'org.apache.http.legacy'

如果您使用的是4.3.5.1之前或之后引入的API,假设httpclient-android库的公共API与httpcomponents相同,则此解决方案将适用于httpcomponents:httpclient的任何依赖项:httpclient库的版本相同。

<强>更新

如果您的代码或任何依赖项明确使用已在httpclient-android库中替换的API,以便不与Android SDK的旧版httpclient版本冲突,则此解决方案将无效。 org.apache.httpcomponents:httpclient提供了构建器(例如HttpClientBuilder,EntityBuilder,MultipartEntityBuilder),它们抽象出所使用的实际类,应该是首选。不幸的是,访问“内部”类/ API和使用Builders都是可能的(可能是为了保持兼容性),但我相信库应该允许一种简洁的方式。

在上面的示例中,Vimeo库直接使用FileEntity构造函数,它将库与特定类耦合,而如果使用EntityBuilder则可以将其解耦。所以我能看到的唯一方法就是修改库源代码,使其与httpclient-android库和Android一般兼容。