最近很火的OkHttp剥洋葱系列
最近很火的OkHttp剥洋葱系列
最近因为Retrofit组合Rxjava系列火的不得了,我也是最近事情较少所以好好研究了一下这种组合。如果你不了解Retrofit你肯定会问跟我们今天说的OkHttp有什么关系:Retrofit内部使用OkHttp实现。当然如果只是因为Retrofit,那我们完全没有必要专门拿出一篇文章来写,毕竟安卓4.4开始Google开始将OkHttp整合到系统里面,为什么要整合OkHttp呢?我们来分析下。
首先列出来几个常用的请求框架吧:
1.HttpURLConnection
这个安卓自带的请求框架应该没什么好说了,总结一下就一个字 繁。当然它也是有优势的,身为基础的请求框架 可塑性很强。基本可以满足你开发的需求,但是代码冗余。
2.Volley
这个框架是我比较常用的,自Volley发布以来一直受大量程序旺的追捧,当然我也是其中一个旺。相比其他框架Volley采用链式请求,代码清晰简介易配置,而且解决了activity消失返回数据的处理问题。实为居家旅行必备良药。但是封装的越完善可塑性就越差,对于一个新手来说,修改Volley请求那叫一个苦逼,别问我为什么。
3.OkHttp
这个框架相比HttpURLConnection封装的要好一些,相比于Volley可塑性那是相当的好。
针对可塑性:HttpURLConnection>OkHttp>Volley
针对简易性:Volley>Okhttp>HttpURLConnection
究竟要用那个框架完全取决于你的项目需求。这里仅仅抛砖引玉
Android studio请引入(强烈建议使用AS):
compile 'com.squareup.okhttp:okhttp:2.4.0'
一,get请求
废话不多说先上代码
OkHttpClient client = new OkHttpClient();
//创建请求可以编辑请求的头 体 等 具体看类代码
Request request = new Request.Builder()
.url("")
.addHeader("", "")
.cacheControl(null)
.build();
Call call = client.newCall(request);
//将线程加入调度,等待结果返回,注意回调函数运行在线程中
call.enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
}
@Override
public void onResponse(Response response) throws IOException {
response.isSuccessful();//是否成功
response.body().string();//返回参数
response.body().byteStream();//获取流输入
}
});
call.cancel();//取消请求调度
注意:回调函数试运行在线程中的!!!使用时请结合handler。这也就是为什么OkHttp会使用在Retrofit和Rxjava中。(具体请移步度娘)
二,post请求
废话不多说先上代码
//方案一 使用json字符串提交数据
OkHttpClient client = new OkHttpClient();
MediaType type = MediaType.parse("application/json; charset=utf-8");
String json = "";
RequestBody body = RequestBody.create(type, json);
Request request = new Request.Builder()
.url("")
.post(body)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
}
@Override
public void onResponse(Response response) throws IOException {
}
});
//方案2 模拟表单提交post请求
OkHttpClient client = new OkHttpClient();
FormEncodingBuilder builder = new FormEncodingBuilder();
builder.add("name", "value");
RequestBody body = builder.build();
Request request = new Request.Builder()
.url("")
.post(body)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
}
@Override
public void onResponse(Response response) throws IOException {
}
});
对于post请求来说大体就这两种写法,不同从根本上来说只是调用了不同的方法,接下来看源码:
public RequestBody build() {
if (content.size() == 0) {
throw new IllegalStateException("Form encoded body must have at least one part.");
}
return RequestBody.create(CONTENT_TYPE, content.snapshot());
}
FormEncodingBuilder 类的build()方法最终调用了RequestBody.create(CONTENT_TYPE, content.snapshot())方法,而 CONTENT_TYPE代码如下
private static final MediaType CONTENT_TYPE = MediaType.parse("application/x-www-form-urlencoded");
结果显而易见,那么也许有人问MediaType.parse():
FORM元素的enctype属性指定了表单数据向服务器提交时所采用的编码类型,默认的缺省值是“application/x-www-form-urlencoded”。
然而,在向服务器发送大量的文本、包含非ASCII字符的文本或二进制数据时这种编码方式效率很低。
在文件上载时,所使用的编码类型应当是“multipart/form-data”,它既可以发送文本数据,也支持二进制数据上载。
下面要讲到文件上传时"application/octet-stream",这是八进制的流。
三,文件上传
废话不多说先上代码
RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
RequestBody requestBody = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addFormDataPart("","",fileBody)
.build();
Request request = new Request.Builder()
.url("")
.post(requestBody)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback()
{
@Override
public void onFailure(Request request, IOException e) {
}
@Override
public void onResponse(Response response) throws IOException {
}
});