您的位置:首页 > 理论基础 > 计算机网络

Android网络请求框架----Okhttp3完全解析(1),使用篇

2017-01-12 10:49 627 查看

1.前言:

最近在改项目的时候发现以前的项目网络请求框架是XUtils,这在过去是一个比较流行的框架,功能强大而且比较全面,但是就XUtils本身的网络请求模块而言,因为Google在android6.0中已经将HttpClient部分给删除,当我把开发工具的compileSdkVersion调到23以上,该框架就会出错,Volley这个框架也是一样,内部也是HttpClient和HttpUrlConnection实现的,所以如果你的项目中还是用了这些古老的框架,还是赶紧换吧。

先来看一张okhttp的脑图(copy而来的)



2.使用:

2.1 集成:

androidstudio直接在gradle中添加:

dependencies

{

compile ‘com.squareup.okhttp3:okhttp:3.5.0’

}

在manifest中添加网络权限。

2.2 使用类型:

2.2.1 Get方式:

步骤: new OkHttpClient ()

Request.Builder方便添加header

call.enqueue异步执行

//get请求方式
private void httpGet() {
String url="http://www.baidu.com";
//client对象,核心类
OkHttpClient client=new OkHttpClient();
//构建者模式,url地址,get方式,
//        final Request request=new Request.Builder().url(url).get().build();

//用requestBuilder可以添加header
Request.Builder requestBuilder = new Request.Builder().url(url);
requestBuilder.addHeader("key","value")

Request request=requestBuilder.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//子线程中
}

@Override
public void onResponse(Call call, Response response) throws IOException {
String str=response.body().string();

//子线程中,response.body()中既可以获取String,也可以获取成byte数组,或者是stream
}
});

}


注意:callback中的failure和success的方法都是在非ui线程中,如果涉及到控件的刷新,一定要在主线程中进行处理。

OkHttp的添加header有两种方式:

使用 header(name,value) 来设置HTTP头的唯一值,相同的key值会覆盖

使用 addHeader(name,value) 来补充新值,不会覆盖相同的key值

使用 header(name) 读取唯一值或多个值的最后一个值

使用 headers(name) 获取所有值

2.2.2 表单提交(key-value形式)

//键值对参数提交(表单提交)
private void httpPost() {
String url="";
//client对象,核心类
OkHttpClient client=new OkHttpClient();
//构建者模式,url地址,get方式,
//        final Request request=new Request.Builder().url(url).get().build();

//这里面添加参数
RequestBody requestbody=new FormBody.Builder()
.add("key1","param1")
.add("key2","param2")
.build();
//用requestBuilder可以添加header
Request.Builder requestBuilder = new Request.Builder().url(url).post(requestbody);

requestBuilder.addHeader("key","value");

Request request=requestBuilder.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//子线程中
}

@Override
public void onResponse(Call call, Response response) throws IOException {
String str=response.body().string();
//子线程中
}
});
}


2.2.3请求体是一个JSON格式的数据

private void httpPostJson() {
String url="";
//client对象,核心类
OkHttpClient client=new OkHttpClient();

//这里面添加参数
Map<String,String> map=new HashMap<>();
map.put("key1","param1");
map.put("key2","param2");
map.put("key3","param3");

//这里用的是fastjson进行解析的
String jsonstr= JSON.toJSONString(map);
RequestBody requestbody = RequestBody.create(MediaType.parse("application/json"), jsonstr);
//用requestBuilder可以添加header
Request.Builder requestBuilder = new Request.Builder().url(url).post(requestbody);
requestBuilder.addHeader("key","header1");

Request request=requestBuilder.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//子线程中
}

@Override
public void onResponse(Call call, Response response) throws IOException {
String str=response.body().string();
//子线程中
}
});
}


post的代码也比较简单,相信大家肯定能都看懂。但是在这里面涉及到一个比较重要的类MediaType,该类来指定post上传的参数类型。

FormBody涉及常见的有三种:

application/x-www-form-urlencoded 数据是个普通表单

multipart/form-data 数据里有文件

application/json 数据是个json

但是好像以上的普通表单并没有指定MediaType,这是因为FormBody继承了RequestBody,它已经指定了数据类型为application/x-www-form-urlencoded。

2.2.4 上传file文件(以图片为例)

//文件的上传
private void httpFileUp() {
OkHttpClient client = new OkHttpClient();
final MediaType MEDIA_TYPE_TEXT = MediaType.parse("image/png");
File file=new File("wy.png");
MultipartBody multipartBody=new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file",file.getName(),RequestBody.create(MEDIA_TYPE_TEXT,file))
.build();

Request request = new Request.Builder()
.url("http://www.baidu.com")
.post(multipartBody)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}

@Override
public void onResponse(Call call, Response response) throws IOException {
}
});

}


对于文件上传,我们用RequestBody的另一个继承类MultipartBody,该类首先需要setType,这里面的参数参有五种类型:

public static final MediaType MIXED = MediaType.parse("multipart/mixed");

public static final MediaType ALTERNATIVE = MediaType.parse("multipart/alternative");

public static final MediaType DIGEST = MediaType.parse("multipart/digest");

public static final MediaType PARALLEL = MediaType.parse("multipart/parallel");

public static final MediaType FORM = MediaType.parse("multipart/form-data");


源码中有相应的解释,当为FORM时,`final MediaType MEDIA_TYPE_TEXT = MediaType.parse(“image/png”);这行代码的类型指定参数可以参考:点击查看,如果接口没有file字段,直接上传文件,可以这样写:.post(RequestBody.create(MEDIA_TYPE_TEXT, file))

2.2.5 下载文件:

private void httpFileDown() {
OkHttpClient mOkHttpClient = new OkHttpClient();
String url = "";
Request request = new Request.Builder().url(url).build();
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {

}

@Override
public void onResponse(Call call, Response response) {
InputStream inputStream = response.body().byteStream();
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(new File("/sdcard/wy.jpg"));
byte[] buffer = new byte[2048];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, len);
}
fileOutputStream.flush();
} catch (IOException e) {

}

}
});
}


文件下载比较简单,其实就是一个get请求,获取到数据流后写进文件中即可。

总结:熟悉以上方法后,我们基本上能够应对android开发中的网络请求了,但是很明显,项目中的接口有很多,每次这样写肯定费事,而且OkHttpClient 一般一个项目中只需要一个全局对象,并且相关的参数比如参数,缓存也没有设置,所以这篇博客权当入门使用,感兴趣的可以看我的下一篇,Android网络请求框架—-Okhttp3完全解析(2),封装框架
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 网络 okhttp3