Problems using unirest in Android Studio

2020-02-05 11:08发布

问题:

I have been getting some errors in my logcat that crash my application while trying to execute some unirest requests. I know you have to generate a special unirest jar with all the dependencies but I have had problems with maven and did not do this, instead I have included the dependencies separate in the libs folder. I have narrowed the problem down to this single error below.

Logcat:

java.lang.VerifyError: com/mashape/unirest/http/options/Options
        at com.mashape.unirest.http.HttpClientHelper.prepareRequest(HttpClientHelper.java:154)
        at com.mashape.unirest.http.HttpClientHelper.request(HttpClientHelper.java:131)
        at com.mashape.unirest.request.BaseRequest.asJson(BaseRequest.java:68)

I understand that the java.lang.verifyerror is caused by a different library given at compile time vs run time. But I don't know how to fix this. Please help, make sure all the dependencies I need is below since I have not used unirest before this.

Build.Gradle:

dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile files('libs/unirest-java-1.3.20.jar')
compile files('libs/rebound-0.3.6.jar')
compile files('libs/commons-io-2.4.jar')
compile files('libs/json-20140107.jar')
compile files('libs/httpmime-4.3.5.jar')
compile files('libs/httpclient-4.3.5.jar')
compile files('libs/httpasyncclient-4.0.2.jar')
compile files('libs/httpcore-4.3.2.jar')
compile files('libs/commons-codec-1.6.jar')
compile files('libs/commons-logging-1.1.3.jar')
}

what my libs folder looks like:

commons-io-2.4.jar
httpcore-4.3.2.jar
httpclient-4.3.5.jar
commons-logging-1.1.3.jar
json-20140107.jar
rebound-0.3.6.jar
unirest-java-1.3.20.jar
commons-codec-1.6.jar
httpmime-4.3.5.jar
httpasyncclient-4.0.2.jar

also included this in the build.gradle because I was getting a duplicate file error while trying to build the gradle file:

packagingOptions {
    exclude 'META-INF/DEPENDENCIES'
    exclude 'META-INF/NOTICE'
    exclude 'META-INF/LICENSE'
    exclude 'META-INF/LICENSE.txt'
    exclude 'META-INF/NOTICE.txt'
}

回答1:

I know it has been a while since you asked that question. I think Android overwrites common classes located in org.apache.http. You can not overwrite them by yourself. Try to relocate the downloaded packages to another location such as surrogate.org.apache.http to use them properly.

From https://hc.apache.org/httpcomponents-client-4.3.x/android-port.html:

Google Android 1.0 was released with a pre-BETA snapshot of Apache HttpClient. To coincide with the first Android release Apache HttpClient 4.0 APIs had to be frozen prematurely, while many of interfaces and internal structures were still not fully worked out. As Apache HttpClient 4.0 was maturing the project was expecting Google to incorporate the latest code improvements into their code tree. Unfortunately it did not happen. Version of Apache HttpClient shipped with Android has effectively become a fork. Eventually Google decided to discontinue further development of their fork while refusing to upgrade to the stock version of Apache HttpClient citing compatibility concerns as a reason for such decision. As a result those Android developers who would like to continue using Apache HttpClient APIs on Android cannot take advantage of newer features, performance improvements and bug fixes.

If you continue reading you will find the following:

Some of the implementation classes had to be copied (or shaded) with different names in order to avoid conflicts with the older versions of the same classes included in the Android runtime. One can increase compatibility of with the stock version of HttpClient by avoiding 'org.apache.http.**.*HC4' classes.

Use

dependencies {
    compile group: 'org.apache.httpcomponents' , name: 'httpclient-android' , version: '4.3.5.1'
}

to include the httpcomponents.

You may have to use the shadowJar plugin to relocate your dependencies if you don't want to relocate them manually.

Edit:

I found this awesome tutorial which worked out for me. Even thought I would recommend to use AndroidAsync or Volley to build up connections to a webserver.