简介:一个处理网络请求的开源项目,是安卓端最火热的轻量级框架,由移动支付Square公司贡献,用于替代HttpUrlConnection和Apache HttpClient。OkHttp可以支持安卓2.3及以上版本,需要jdk1.7及以上;OkHttp有2.x和OkHttp3.x版本之间的部分方法的使用有一点的差异。
优点(百度百科):
1、允许连接到同一个主机地址的所有请求,提高请求效率
2、共享Socket,减少对服务器的请求次数
3、通过连接池,减少了请求延迟
4、缓存响应数据来减少重复的网络请求
5、减少了对数据流量的消耗
6、自动处理GZip压缩
对于OkHttp在使用前,需要在工程中引入OkHttp包,OkHttp还依赖另一个okio包,同样需要引入。也可以在相应的model中的build.gradle配置文件中填入,然后将工程同步一下,环境会自动去下载需要的包:
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.squareup.okio:okio:1.7.0'
//可以修改版本号
<user-permission andriod:name="andriod.premission.INTERNET"/> <!--用户连接网络权限-->
OkHttp的初次学习需要掌握的基本类有:OkHttpClient、RequestBody、Request、Call和Response... ...
1、OkHttpClient:
对于该类创建对象实例化的方式有两种:标准默认型还有自定义的形式
//标准形式:
OkHttpClient mOkHttpClient = new OkHttpClient();
//自定义形式:
OkHttpClient mOkHttpClient = new OkHttpClient.Builder()
.connectTimeout(10,TimeUtil.SECONDS) //为新连接设置默认连接超时时长,第一个参数时大小,第二个参数是单位
.readTimeout(10,TimeUtil.SECONDS) //设置新连接的默认读取超时时长
.writeTimeout(10,TimeUtil.SECONDS) //设置新连接的默认写入超时时长
.cache(setCache) //设置用于读取和写入缓存响应的响应缓存 [1]
.build();
[1]:参数为Cache对象 File filePath = new File(getExternalCacheDir(),"netCache"); int cacheSize = 10 * 1024 * 1024; Cache setCache = new Cache(filePath,cacheSize); 注:在OkHttp2.+的版本中设置以上的超时的方法与3.+版本不同: mOkHttpClient.setConnectTimeout(10,TimeUtil.SECONDS); mOkHttpCLient.setConnectTimeout(10,TimeUtil.SECONDS); mOkHttpClient.setConnectTimeout(10,TimeUtil.SECONDS); mOkHttpClient.setCache(setCache);
2、RequestBody:
该类对于OkHttp的post方法使用,是请求体类,用于上传数据使用
核心方法:contentType、contentLength、create、writeTo方法... ...
public abstract MediaType contentType()
public long MediaType contentLength()
public abstract void writeTo(BufferedSink sink)
public static RequestBody create(MediaType contentType,String content) [2]
//[2]:第二个参数可以是多种类型;该类存在create的多个重载方法,api点这
//该类的对象实例化方式:
MediaType mMediaType = MediaType.parse("application/octet-stream"); //
File putFile = new File(Environment.getExternaStorageDirectory(),"文件名.扩展名"); //父路径和子路径两个参数拼接起来为文件地址绝对地址
RequestBody mRequestBody = RequestBody.create(mMediaType,putFile); [3]
//[3]:第一、第二参数类型均为多种,使用create方法一般用于上传文件或字符串类型数据,对于上传键值对类型数据将会使用另一种方法(另一方式FormBody)
RequestBody mRequestBody = FormBody.Builder()
.add("key","value1")
.add("key","value2")
.build();
3、Request:
该类用于生成网络连接请求对象,包括多中信息:请求参数,请求头,请求方式...
常用方法有:url、post、method、headers等方法
Request mRequest = new Request.Builder()
.url("http://www.baidu.com")
.post(mRequestBody) [4]
.build();
/*[4]:如果不显示调用post方法,该此网络请求将使用get方式请求网络,其中的参数是请求体对象的示例,使用post方式上传数据比get方式更安全,数据大小不受
限制,可以传递更多的参数(对于长表单数据,上传文件很好用)*/
4、Call:
该类是网络请求执行的最后一个需要实例的对象,该类提供了网络请求的同步与异步连接方式,所有的连接都不在UI线程中,如果在网络请求后,需要更新UI布局就需要调用Handler,有方法:runOnUiThread()方法
Call mCall = mOkHttpClient.newCall(mRequest);
//使用异步网络连接
mCall.enqueue(new CallBack(){
@override
public void onFailure(Call call,IOException e){
//网络连接失败
}
@override
public void onResponse(Call call,Response response){
if(response.isSuccessful()){
//请求数据成功,返回code为200~300 [5]
}else{
//请求数据失败
}
}
});
[5]:response.isSuccessful()源码:
public boolean isSuccessful(){
return code >= 200 && code <= 300;
}
//使用同步方式需要开启新的子线程,耗时操作不允许在UI主线程中运行
new Thread(new Runnable(){
Call mCall = mOkHttpClient.newCall(mRequest);
Response mResponse = mCall.execute(); //涉及到的Response对象知识下一点解说
if(mResponse.isSuccessful()){
//网络同步请求成功,更新UI布局需要使用runOnUiThread方法
}else{
}
}).start(); //创建一个子线程后需要使用start方法启动该线程
注:runOnUiThread(new Runnable(){
@override
public void run(){
//更新UI的逻辑代码
}
});
//同步方法会阻塞当前线程的执行,异步方法不会阻塞当前线程的执行
5、Response:
该类是网络请求后的响应信息对象,对于服务器返回的数据均存放在该示例对象中,而且对于Response实例一次请求中只能有一次有效调用,如果调用两次将会出现程序错误,因此,这就使得在需要多次使用数据前就要将Response实例中的数据保存下来,Response类提供了多种方法:body、code、protocol、request、isSuccessful、headers(响应头对象)、toString...
Response mResponse = mCall.execute();
if(mResponse.isSuccessful()){
String str = mResponse.body().string(); [6]
int code = mResponse.code();
Protocol protocol = mResponse.protocol();
Request request = mResponse.request();
String head = mResponse.toString();
Log.i("Response响应信息集:","" + str + code + protocol + request + head);
}
/*[6]:body为获取的数据没内容,该数据可以为:转化为字符串、字节流、字符流、字节数组等形式数据,有此属性就奠定了OkHttp下载文件的功能,当然可以上传文
件,这是就与第2点联系起来了,第二点中的RequsetBody的实例方法可以将本地文件“放置”到请求体中,这是,服务器端在接收参数时就可以得到用户上传的文件数据*/
这五个点学习后,这时,就可以写出基本的get、post同步或异步的网络连接了。对于OkHttpClient表示HTTP请求的客户端类,大多数情况下推荐只使用创建一个该对象的实例,全局使用
这里贴一个完整的关于post请求的异步方法示例:
public class PostAsyn(){
private TextView tvShowNetInfo;
public static OkHttpClient okHttpClient;
static(
okHttpClient = new OkHttpClient.Builder()
.connectTimeout(15,TimeUnit.SECONDS)
.readTimeout(15,TimeUnit.SECONDS)
.writeTimeout(15,TimeUnit.SECOND)
.build();
);
@Overvide
public void onCreate(Bundle saveInstanceState){
super.onCreate(saveInstanceState);
setContentView(R.layout.activity_main);
tvShowNetInfo = (TextView) findViewId(.tv_show_net_info);
postAsynDate();
}
public void postAsynData(){
RequestBody requestBody = new FormBody.Builder()
.add("key1","value1")
.add("key2","value2")
.build();
Request requset = new Request.Builder()
.url("http://www.baidu.com")
.post(requestBody)
.build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback(){
@Overvide
public void onFailure(Call call,IOException e){
goUiThread("网络连接失败");
}
@Overvide
public void onResponse(Call call,Response response){
if(response.isSuccessful()){
goUiThread("请求数据成功,响应码:" + response.code());
}else{
goUiThread("网络连接成功,但是没有响应数据,响应码:" + response.code());
}
}
}
);
}
private void goUiThread(final String str){
runOnUiThread(new Runnable(){
@Overvide
public void run(){
tvShowNetInfo.setText(str);
}
});
}
}
//对应的布局文件略
//这只是基本的OkHttp操作,其还提供更多的高级使用,例如使用缓存,发送复杂请求体等