一、开发背景:
我目前在做的是一个3年左右的老项目,项目开始的时候okhttp还不像现在这么火,基本上使用HttpURLConnection类来实现所有的HTTP请求,当时采用的是xUtils框架来实现异步的,回调式的接口请求。现在发现xUtils这套框架存在几个很大的问题。
老框架的性能问题:
1、xUtils的图片加载任务会阻塞Http请求,因为xUtils中的图片加载框架BitmapUtils和网络请求框架HttpUtils的线程池是共用的,这个线程池的大小默认为3,也就是说当我在下载图片的时候会阻塞Http请求数据接口的任务。这样会带来一个严重后果,当一个页面图片很多的时候,我打开一个新的页面,新的页面需要下载相应的json字符串来显示,但是由于线程池里满满的都是图片下载任务,所以用户必须等所有图片都下载完毕之后才能调json的接口,本来很快就可以显示的页面现在却要等无意义的图片的下载,大大降低了用户体验。
2、xUtils框架连接握手太频繁,根据抓包结果来看,xUtils在完成一次Http请求之后,会主动发送挥手的FIN报文,将TCP连接关闭。这样的话如果短期内频繁请求同一个服务器多次,那么每次都要重新进行三次握手的步骤,浪费了许多时间,根据抓包结果来看,大约每次连接会浪费300ms左右的时间。抓包截图如下
可以看出倒数第3行是由Android客户端主动向服务器发送FIN报文,而且发送的时间是紧接着接口数据传输完毕后的。也就是说几乎没有进行连接保活,这样如果短时间请求同一个接口多次的话,每次调用都会执行一次握手,大量的握手会消耗大量的时间,不适合目前APP会大量调用接口的情况。
3、Android 6.0发布之后,谷歌已经将所有旧版的HttpURLConnection,HttpClient,和一些和apache有关包的类和方法定义为过时方法,并且Android SDK 23之后不再内置旧版的类和接口,需要额外引用jar包,为了代码的健壮性也需要抛弃旧版Android的HTTP框架。
OkHttp3.0的引入和配置:
在我的编程经验里来看,优秀的开源框架引入起来总不会是一帆风顺的,OkHttp也是如此,这里讲讲引入过程中的几个大坑
首先在gradle里添加引用(Eclipse可以下载连个jar包直接导入项目okhttp-3.3.1.jar,okio-1.8.0.jar):
compile 'com.squareup.okhttp3:okhttp:3.2.0'
导入完打一个带签名的包马上就会出问题
注意上面这些gradle编译的报错指示note,并不影响编译进程,也不会影响打出来的apk包。这些note是progard在混淆的时候发现有重复的类报出来的,虽然不影响使用但是这里还是要分析一下,去掉重复的类。报错的矛头指向旧版的旧版的HttpURLConnection和HttpClient的类,说它们重复了,重复的包主要是org.apache.commons.codec包。
于是我在项目里搜索该包的引用,首先发现,我现在的编译版本是23,但是23已经没有这些类了,于是我添加了apache旧框架的支持jar包,在build.gradle里是这样配置的:
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "com.xxx.app"
minSdkVersion 15
targetSdkVersion 17
versionCode 1
versionName '1.0.0.0'
multiDexEnabled true
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
productFlavors {
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
packagingOptions {
exclude 'META-INF/LICENSE.txt'
}
useLibrary 'org.apache.http.legacy'
...
}
重点是这一句useLibrary 'org.apache.http.legacy'
他会将SDK目录中\platforms\android-23\optional\org.apache.http.legacy.jar这个jar包自动添加到项目中来,而这个jar包里面就有apache的一些类。
但它又是怎样重复的呢?经过一番搜寻我又发现在xUtils这个第三方库中有一个commons-codec.jar
正是这个jar包和org.apache.http.legacy.jar中的类出现了重复,于是把xUtils第三方库中的