0

这是我正在使用的库: 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>

请帮忙 :(

谢谢,

PS 这是第一种情况的堆栈跟踪:

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) 
4

1 回答 1

2

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

第一种情况失败,因为HttpClientBuilder在 httpclient:4.3 上引入。

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

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

此解决方案将适用于httpcomponents:httpclient您是否使用在 4.3.5.1 之前或之后引入的 API,而不是更高版本,假设 httpclient-android 库的公共 API 与 httpcomponents:httpclient 库相同版本。

更新

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

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

于 2017-10-07T23:23:13.030 回答