OkHttp个人记录使用详解
说明
在这里记录一下使用okhttp的常用方法,以便日后开发的时候方便自己查看,毕竟人脑子容量有限,很多东西特别是代码,想要像背课文一样完全记住,不知道有没有人做的到,反正我是做不到,所以记录一下,方便以后查看。
一、基本使用流程
1.导入依赖
在对应的Module的gradle中添加在对应的Module的gradle中添加
compile 'com.squareup.okhttp3:okhttp:3.5.0'
然后同步一下项目即可
2.在代码中常用基本使用
//1.创建okhttpclient对象
OkHttpClient client = new OkHttpClient.Builder()
.readTimeout(5,TimeUnit.SECONDS)//设置超时
.cache(cache)//设置缓存,不需要的可以不加,也可以在request中从新设置
.build();
//2.创建request请求对象
Request request = new Request.Builder()
.url("")//请求的网址
.cacheControl(new CacheControl.Builder().noCache().build())//缓存控制器
.get()//请求方式
.addHeader("","")//添加请求头
.build();
//3.穿件Call 对象
Call call = client.newCall(request);
//4.执行网络请求获取response
//同步,需要try或者抛出异常,
//这里注意,不能再UI线程中使用,会造成阻塞,可以利用ronOnTuchThread 或者Hanlder完成线程操作
Response response1 = call.execute();
//异步方法,需要传入一个Callback的实现类
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//失败回调
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//成功回调,因为是异步执行的,所以可以在这里进行更新UI的操作。
}
});
二、各种请求方式的详细使用及说明(以后会不断增加内容,现在先写自己用到过的和会的。)
基本使用方法已在上一个标题中写出具体步骤,下面的内容只根据不同写出有差别不分的代码,
主要不同表现在request上
1.get
//第一种方式常规方式,方位一个地址,返回数据,如果不写get,默认也是get方法请求网址的。
Request request = new Request.Builder()
.url("")//请求的网址
.get()//请求方式
.build();
//第二种方式,创建httpurl,提交请求参数
HttpUrl httpUrl = new HttpUrl.Builder()
.addQueryParameter("name","twomonth")
.addQueryParameter("password","123456789")
.build();
Request request1 = new Request.Builder().url(httpUrl).get().build();
2.post
提交表单
FormBody formBody = new FormBody.Builder()
.add("key","value")
.build();
Request request1 = new Request.Builder()
.url("")
.post(formBody)
.build();
提交字符串(例如json)
JSONObject jsonObject = new JSONObject();
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON, jsonObject.toString());
Request request = new Request.Builder()
.url("")
.post(body)
.build();
数据流的方式上传文件
File file = new File(Environment.getExternalStorageDirectory(), "1.png");
RequestBody requestBody2 = null;
if (!file.exists()){
Toast.makeText(this, "文件不存在", Toast.LENGTH_SHORT).show();
}else{
requestBody2 = RequestBody.create(MediaType.parse("application/octet-stream"), file);
}
Request request1 = new Request.Builder()
.url("")
.post(requestBody2)
.build();
Post方式提交分块请求,可以上传文件
MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("key", "value")
.addFormDataPart("key", "value.png",
RequestBody.create(MEDIA_TYPE_PNG, new File("")))
.build();
Request request = new Request.Builder()
.header("Authorization", "Client-ID ")
.url("https://api.imgur.com/3/image")
.post(requestBody)
.build();
三、Response 响应
通常使用
call.enqueue(new Callback() { //异步方法,需要传入一个Callback的实现类
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//response中便是响应中的信息,根据内容不同采取不同的解析方式
//这里只是字符串类型的响应体,接触到更多后会一步步添加该部分内容
response.body().string();
}
});
输入流下载文件
//这里是自己写的一个文件管理类,事实上就是根据url穿件一个文件,完全可以用new File()代替。
File file = FileStorageManager.getInstance().getFileByName(url);
byte[] buffer = new byte[1024*500];
int len;
FileOutputStream fileOutputStream = new FileOutputStream(file);
InputStream inputStream = response.body().byteStream();
while ((len=inputStream.read(buffer,0,buffer.length))!=-1){
Logger.error("tag:",len+"");
fileOutputStream.write(buffer,0,len);
fileOutputStream.flush();
}
//关闭输入输出流
fileOutputStream.close();
inputStream.close();
四、HTTP头部的设置和读取
Request request = new Request.Builder()
.url("https://github.com")
.header("User-Agent", "agent")
.addHeader("Accept", "text/html")
.build();
- 使用header(name,value)来设置HTTP头的唯一值,如果请求中已经存在响应的信息那么直接替换掉。
- 使用addHeader(name,value)来补充新值,如果请求头中已经存在name的name-value,那么还会继续添加,请求头中便会存在多个name相同而value不同的“键值对”。
- ==使用header(name)读取唯一值或多个值的最后一个值 ==
- ==使用headers(name)获取所有值 ==
Cache缓存的使用
关于缓存的理解直接上图,从别人的教学视频中截取到的,感觉比较清晰
使用测试:
int maxSize = 10*1024*1024;
//设置缓存大小和目录
Cache cache = new Cache(new File("/testSource"),maxSize);
//用OkHttpClient.Builder()设置缓存到client
OkHttpClient okHttpClient = new OkHttpClient.Builder().cache(cache).build();
//访问一个有缓存的网址
Request request = new Request.Builder().url("http://www.qq.com").build();
//以下为测试用例子
//第一次访问
Response response = okHttpClient.newCall(request).execute();
System.out.println("network response:"+response.networkResponse());
System.out.println("cache response:"+response.cacheResponse());
//第二次访问
System.out.println("-----------------------------------------");
Response response2 = okHttpClient.newCall(request).execute();
System.out.println("network response:"+response.networkResponse());
System.out.println("cache response:"+response.cacheResponse());
输出结果:
network response:Response{protocol=http/1.1, code=200, message=OK, url=https://www.qq.com/}
cache response:null
-----------------------------------------
network response:Response{protocol=http/1.1, code=200, message=OK, url=https://www.qq.com/}
cache response:null
说明我们设置使用的缓存成功了。
Request request = new Request.Builder().url("http://www.qq.com")
.cacheControl(new CacheControl.Builder().noCache().build())
.build();
这里我们也可以在request中单独设置cacheControl,noCache()表示不使用缓存,还有很多方法,自己可以体验一下。