okhttp的使用
主要三个步骤:
1.创建OkHttpClient实例
2.使用构造器创建请求
3.提交请求
概括为
OkHttpClient client = new OkHttpClient();//1.
Request request = new Request.Builder()
.url(url)
.build();//2.
Response response = client.newCall(request).execute();//3. enqueue()异步
下面是具体的几种使用方式
Get 同步请求
Get 异步请求
Post 异步请求
Post 异步请求——使用RequestBody传递Json或File对象
Post 异步请求——使用MultipartBody同时传递键值对参数和File对象
Post 异步请求——自定义一个类,继承RequestBody,实现流的上传
Post 异步请求——下载文件
- Get 同步请求
public void getDataSync(){
new Thread(new Runnable() {
@Override
public void run() {
OkHttpClient okHttpClient = new OkHttpClient();//1.
Request request = new Request.Builder()
.url("http://www.baidu.com")
.build();//2.
try {
Response response = okHttpClient.newCall(request).execute();//3.
if(response.isSuccessful()){
//此时的代码执行在子线程,修改UI的操作请使用handler跳转到UI线程。
Log.d(TAG,"response.code()=="+response.code());
Log.d(TAG,"response.message()=="+response.message());
Log.d(TAG,"res=="+response.body().string());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
- Get 异步请求
public void getDataAsync(){
OkHttpClient okHttpClient = new OkHttpClient();//1.
Request request = new Request.Builder()
.url("http://www.baidu.com")
.build();//2.
okHttpClient.newCall(request).enqueue(new Callback() {//3.
@Override
public void onFailure(Call call, IOException e) {}
@Override
public void onResponse(Call call, Response response) throws IOException {
//回调的方法执行在子线程。
if(response.isSuccessful()){
Log.d(TAG,"response.code()=="+response.code());
Log.d(TAG,"response.body().string()=="+response.body().string());
}
}
});
}
- Post 异步请求
public void postDataWithParames(){
OkHttpClient okHttpClient = new OkHttpClient();//1.
//创建表单请求体
FormBody formBody = new FormBody.Builder()
.add("userName", "beibei")
.build();
Request request = new Request.Builder()
.url("http://www.baidu.com")
.post(formBody) //FormBody extends RequestBody
.build();
okHttpClient.newCall(request).enqueue(new Callback() {//3.
@Override
public void onFailure(Call call, IOException e) {}
@Override
public void onResponse(Call call, Response response) throws IOException {}
});
}
- Post 异步请求——使用RequestBody传递Json或File对象
public void postJson(){
OkHttpClient okHttpClient = new OkHttpClient();//1.
MediaType JSON = MediaType.parse("application/json;charset=utf-8");
String jsonStr = "{\"username\":\"lisi\"}";
RequestBody requestBody = RequestBody.create(JSON, jsonStr);
Request request = new Request.Builder()
.url("http://www.baidu.com")
.post(requestBody)
.build();//2.
okHttpClient.newCall(request).enqueue(new Callback() {//3.
@Override
public void onFailure(Call call, IOException e) {}
@Override
public void onResponse(Call call, Response response) throws IOException {}
});
}
public void postFile(){
OkHttpClient okHttpClient = new OkHttpClient();//1.
MediaType fileType = MediaType.parse("File/*");
File file = new File("path");
RequestBody requestBody = RequestBody.create(fileType, file);
Request request = new Request.Builder()
.url("http://www/baidu.com")
.post(requestBody)
.build();//2.
okHttpClient.newCall(request).enqueue(new Callback() {//3.
@Override
public void onFailure(Call call, IOException e) {}
@Override
public void onResponse(Call call, Response response) throws IOException {}
});
}
- Post 异步请求——使用MultipartBody同时传递键值对参数和File对象
/**
* 使用MultipartBody同时传递键值对参数和File对象
*
* FromBody传递的是字符串型的键值对,RequestBody传递的是多媒体,那么如果我们想二者都传递怎么办?此时就需要使用MultipartBody类。
*/
public void postMultipart(){
OkHttpClient okHttpClient = new OkHttpClient();//1.
File file = new File("path");
MultipartBody multipartBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("groupId", "1")
.addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse("file/*"), file))
.build();
Request request = new Request.Builder()
.url("URLContant.CHAT_ROOM_SUBJECT_IMAGE")
.post(multipartBody)//MultipartBody extends RequestBody
.build();//2.
okHttpClient.newCall(request).enqueue(new Callback() {//3.
@Override
public void onFailure(Call call, IOException e) {}
@Override
public void onResponse(Call call, Response response) throws IOException {}
});
}
- Post 异步请求—— 自定义一个类,继承RequestBody,实现流的上传
public void customRequestBody(){
RequestBody body = new RequestBody() {
@Override
public MediaType contentType() {
return null;
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
FileInputStream fio = new FileInputStream(new File("fileName"));
byte[] buffer = new byte[1024 * 8];
if (fio.read(buffer) != -1) {
sink.write(buffer);
}
}
};
OkHttpClient client = new OkHttpClient();//1.
Request request = new Request.Builder()
.url("http://www.baidu.com")
.post(body)
.build();//2.
client.newCall(request).enqueue(new Callback() {//3.
@Override
public void onFailure(Call call, IOException e) {}
@Override
public void onResponse(Call call, Response response) throws IOException {}
});
}
- Post 异步请求—— 下载文件
public void postDownLoad(){
OkHttpClient okHttpClient = new OkHttpClient();//1.
//创建表单请求体
FormBody formBody = new FormBody.Builder()
.add("userName", "beibei")
.build()
Request request = new Request.Builder()
.url("http://www.baidu.com")
.post(formBody)
.build();//2.
okHttpClient.newCall(request).enqueue(new Callback() {//3.
@Override
public void onFailure(Call call, IOException e) {}
@Override
public void onResponse(Call call, Response response) throws IOException {
//从服务器得到输入流对象
InputStream inputStream = response.body().byteStream();
long sum = 0;
File fileDir = new File("mDestFileDir");
if(!fileDir.exists()){
fileDir.exists();
}
File file = new File(fileDir, "mDestFileName");
FileOutputStream fos = new FileOutputStream(file);
byte[] buf = new byte[1024 * 8];
int len = 0;
while ((len = inputStream.read(buf))!=-1){
fos.write(buf,0,len);
}
fos.flush();
// return file;
}
});
}
主要类的介绍
1、OKHttpClient类详解
- 1、里面包含了很多对象,其实OKhttp的很多功能模块都包装进这个类,让这个类单独提供对外的API,这种外观模式的设计十分的优雅。外观模式。
- 2、而内部模块比较多,就使用了Builder模式(建造器模式)。Builder模式(建造器模式)
- 3、它常用的一个方法:newCall。返回一个Call对象(一个准备好了的可以执行和取消的请求)。
使用时,在构造了OKHttpClient
后,又new了一个Rquest
对象。那么咱们就来看下Request,说道Request又不得不提Response
。所以咱们一起讲了
2、Request、Response类详解
- 1、Request、Response分别抽象成请求和响应
- 2、其中Request包括
Headers
和RequestBody
,而RequestBody是abstract的,他的子类是有FormBody
(表单提交)和MultipartBody
(文件上传),分别对应了两种不同的MIME类型
FormBody :"application/x-www-form-urlencoded"
MultipartBody:"multipart/"+xxx.
- 3、其中Response包括
Headers
和ResponseBody
,而ResponseBody是abstract的,他的子类也是有两个:RealResponseBody
和CacheResponseBody
,分别代表真实响应和缓存响应。- 4、由于RFC协议规定,所以所有的头部信息不是随便写的,request的header与response的header的标准都不同。具体的见 List of HTTP header fields。OKHttp的封装类Request和Response为了应用程序编程方便,会把一些常用的Header信息专门提取出来,作为局部变量。比如contentType,contentLength,code,message,cacheControl,tag...它们其实都是以name-value对的形式,存储在网络请求的头部信息中。
使用时,用builder构建了Request对象,然后执行OKHttpClient.的newCall方法,看下newCall里面都做什么操作
/**
* Prepares the {@code request} to be executed at some point in the future.
*/
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
Call是个什么东西,那咱们看下Call这个类
3、Call类详解
Call: HTTP请求任务封装
可以说我们能用到的操纵基本上都定义在这个接口里面了,所以也可以说这个类是OKHttp类的核心类了。
我们可以通过Call对象来操作请求了。而Call接口内部提供了Factory工厂方法模式(将对象的创建延迟到工厂类的子类去进行,从而实现动态配置)

在源码中,
OKHttpClient
实现了Call.Factory
接口,返回了一个RealCall
对象。那我们就来看下RealCall这个类
网友评论