OkHttp3的简单使用(一)
一、导入
1)gradle方式:
compile 'com.squareup.okhttp3:okhttp:3.8.0'(okhttp 最新版)
compile 'com.squareup.okio:okio:1.13.0'(okio最新版)
2)jar包导入
okhttp-3.3.0.jar
okio-1.8.0.jar
3)权限
<!--网络访问权限-->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- 外置存储存取权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
二、使用
同步:execute() 异步:enqueue(new Callback()...)
一)get请求
String url="http://www,baidu.com/";
OkHttpClient client=new OkHttpClient();
Request request=new Request.Builder()
.url(url)
.build();
Call call=client.newCall(request); //同步
try {
Response response=call.execute();
if(response.isSuccessful()){
Log.e(TAG, "onCreate: "+response.body().string() );
}
} catch (IOException e) {
e.printStackTrace();
} //异步
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//失败
Log.e(TAG, "onFailure: 失败:"+e.getMessage() );
} @Override
public void onResponse(Call call, Response response) throws IOException {
//成功
Log.e(TAG, "onResponse: "+response.body().string() );
}
});
二)POST请求JSON格式
String url="http://www,baidu.com/";
OkHttpClient client=new OkHttpClient(); MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON, "你的json"); Request request=new Request.Builder()
.url(url)
.post(requestBody)
.build(); Call call=client.newCall(request); //同步
try {
Response response=call.execute();
if(response.isSuccessful()){
Log.e(TAG, "onCreate: "+response.body().string() );
}
} catch (IOException e) {
e.printStackTrace();
} //异步
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//失败
Log.e(TAG, "onFailure: 失败:"+e.getMessage() );
} @Override
public void onResponse(Call call, Response response) throws IOException {
//成功
Log.e(TAG, "onResponse: "+response.body().string() );
}
});
三)POST请求表单格式
post请求创建request和get是一样的,只是post请求需要提交一个表单,就是RequestBody。表单的格式有好多种,普通的表单是:
RequestBody body = new FormBody.Builder()
.add("键", "值")
.add("键", "值")
...
.build();普通表单:
RequestBody body = new FormBody.Builder()
.add("键", "值")
.add("键", "值")
...
.build();
FormBody继承了RequestBody,它已经指定了数据类型为application/x-www-form-urlencoded
private static final MediaType CONTENT_TYPE = MediaType.parse("application/x-www-form-urlencoded");
四)上传文件
//创建 MediaType 设置上传文件类型
MediaType MEDIATYPE = MediaType.parse("text/plain; charset=utf-8");
//获取请求体
RequestBody requestBody = RequestBody.create(MEDIATYPE, file);
//创建请求
Request request = new Request.Builder().url("http://www.baidu.com")
.post(requestBody)
.build();
五)上传Multipart文件
//定义上传文件类型
private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)//数据格式 带有文件
.addFormDataPart("title", "wangshu") //键值对参数
.addFormDataPart("image", "wangshu.jpg",
RequestBody.create(MEDIA_TYPE_PNG, new File("/sdcard/wangshu.jpg"))) //要上传的文件
.build();RequestBody的数据格式都要指定Content-Type,常见的有三种:
application/x-www-form-urlencoded 数据是个普通表单
multipart/form-data 数据里有文件
application/json 数据是个jsonMediaType的创建:
MediaType MEDIATYPE = MediaType.parse("text/plain; charset=utf-8");如果表单是个json:
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON, "你的json");如果数据中包含文件:
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("键","值”)
.addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse("image/png"), file))
.build();
另外如果你上传一个文件不是一张图片,但是MediaType.parse("image/png")里的"image/png"不知道该填什么,可以参考(http://www.w3school.com.cn/media/media_mimeref.asp)。常见的文件类型:
参数 说明
text/html HTML格式
text/plain 纯文本格式
text/xml XML格式
image/gif gif图片格式
image/jpeg jpg图片格式
image/png png图片格式
application/xhtml+xml XHTML格式
application/xml XML数据格式
application/atom+xml Atom XML聚合格式
application/json JSON数据格式
application/pdf pdf格式
application/msword Word文档格式
application/octet-stream 二进制流数据
六)设置超时时间和缓存
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS) //设置连接超时
.writeTimeout(20, TimeUnit.SECONDS) //写入超时
.readTimeout(20, TimeUnit.SECONDS) //读取超时
.cache(new Cache(sdcache.getAbsoluteFile(), cacheSize));
OkHttpClient mOkHttpClient=builder.build();
七)添加请求头
okhttp3添加请求头,需要在Request.Builder()使用.header(String key,String value)或者.addHeader(String key,String value);
使用.header(String key,String value),如果key已经存在,将会移除该key对应的value,然后将新value添加进来,即替换掉原来的value;
使用.addHeader(String key,String value),即使当前的可以已经存在值了,只会添加新value的值,并不会移除/替换原来的值。
还有.headers(Headers headers)添加请求头集合Request request = new Request.Builder()
.url("https://api.github.com/repos/square/okhttp/issues")
.header("User-Agent", "OkHttp Headers.java")
.addHeader("Accept", "application/json; q=0.5")
.addHeader("Accept", "application/vnd.github.v3+json")
.build();/**
* 设置请求头
* @param headersParams
* @return
*/
private Headers SetHeaders(Map<String, String> headersParams){
Headers headers=null;
okhttp3.Headers.Builder headersbuilder=new okhttp3.Headers.Builder(); if(headersParams != null)
{
Iterator<String> iterator = headersParams.keySet().iterator();
String key = "";
while (iterator.hasNext()) {
key = iterator.next().toString();
headersbuilder.add(key, headersParams.get(key));
Log.d("get http", "get_headers==="+key+"===="+headersParams.get(key));
}
}
headers=headersbuilder.build(); return headers;
}
八)取消请求
使用call.cancel()可以立即停止掉一个正在准备的同步/异步请求call。如果一个线程正在写请求或者读响应,将会引发IOException。
当用户离开一个应用时或者跳到其他界面时,使用Call.cancel()可以节约网络资源,另外不管同步还是异步的call都可以取消。
也可以通过tags来同时取消多个请求。当你构建一请求时,使用RequestBuilder.tag(tag)来分配一个标签。
之后你就可以用OkHttpClient.cancel(tag)来取消所有带有这个tag的call。
九)自动管理Cookie
Request经常都要携带Cookie,上面说过request创建时可以通过header设置参数,Cookie也是参数之一。就像下面这样:
Request request = new Request.Builder()
.url(url)
.header("Cookie", "xxx")
.build();OkHttp可以不用我们管理Cookie,自动携带,保存和更新Cookie。
方法是在创建OkHttpClient设置管理Cookie的CookieJar:private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.cookieJar(new CookieJar() {
@Override
public void saveFromResponse(HttpUrl httpUrl, List<Cookie> list) {
cookieStore.put(httpUrl.host(), list);
} @Override
public List<Cookie> loadForRequest(HttpUrl httpUrl) {
List<Cookie> cookies = cookieStore.get(httpUrl.host());
return cookies != null ? cookies : new ArrayList<Cookie>();
}
})
.build();这样以后发送Request都不用管Cookie这个参数也不用去response获取新Cookie什么的了。还能通过cookieStore获取当前保存的Cookie。
最后,new OkHttpClient()只是一种快速创建OkHttpClient的方式,更标准的是使用OkHttpClient.Builder()。后者可以设置一堆参数,例如超时时间什么的。
注意事项
Android 4.0之后要求网络请求必须在工作线程中运行,不允许在主线程中运行。因此如果使用OkHttp3的同步方法,需要新起工作线程进行调用。
一般情况下我们希望获得Response返回的字符串,可以通过response.body().string()获取;
如果希望获得返回的二进制字节数组,则调用response.body().bytes();
如果想获取到返回的InputStream,则调用response.body().byteStream()。
异步请求enqueue的回调是子线程,非主线程,所以是不能直接操作UI界面的。
响应体的string()方法适用于获取小数据信息,如果返回的数据太大(超过1MB),
建议使用stream()获取返回的数据,因为string()方法会将整个文档加载到内存中。
参考:
http://blog.csdn.net/lmj623565791/article/details/47911083
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0106/2275.html
http://www.2cto.com/kf/201604/501946.html
http://blog.csdn.net/feixiang_gao/article/details/53760705
http://blog.csdn.net/chinaboyliusir/article/details/51261929
http://blog.csdn.net/wwwkp1236/article/details/51374320
https://github.com/MrZhousf/OkHttp3
OkHttp3的简单使用(一)的更多相关文章
- OkHttp3的简单使用(二)
OkHttp3的简单封装 public class OkHttpUtil { public static final String TAG="OkHttpUtil"; privat ...
- Okhttp3的简单使用
1.get请求: /** * *okhttp get请求 * */ public class MainActivity extends AppCompatActivity { private stat ...
- 深入解析OkHttp3
OkHttp是一个精巧的网络请求库,有如下特性: 1)支持http2,对一台机器的所有请求共享同一个socket 2)内置连接池,支持连接复用,减少延迟 3)支持透明的gzip压缩响应体 4) ...
- Spring Cloud OkHttp设计原理
Spring Cloud 框架最底层核心的组件就是服务调用方式,一般Spring Cloud框架采用的是HTTP的调用框架,本文将在 Spring Cloud应用场景下,介绍组件OkHttp3的设计原 ...
- okhttp3 get post 简单封装
最近打算在新项目中使用 okhttp3, 简单封装了一下异步 get post 因为 CallBack 也是在子线程中执行,所以用到了 Handler public class MyOkHttpCli ...
- OkHttp3几个简单的例子和在子线程更新UI线程的方法
okHttp用于android的http请求.据说很厉害,我们来一起尝尝鲜.但是使用okHttp也会有一些小坑,后面会讲到如何掉进坑里并爬出来. 首先需要了解一点,这里说的UI线程和主线程是一回事儿. ...
- 让你Android开发更简单
转载:http://www.jianshu.com/p/22ff8b5fdadc 搭建一个新的Android项目,你会怎么做? 每个人对应用框架的理解不相同,但是最终达到的效果应该是一样: ①降低项目 ...
- Android--Retrofit+RxJava的简单封装(三)
1,继续接着上一篇的讲讲,话说如果像上一篇这样的话,那么我们每一次请求一个结构都要创建一堆的Retrofit对象,而且代码都是相同的,我们可以试试封装一下 先创建一个HttpMethods类,将Ret ...
- retrofit2 okhttp3 RxJava butterknife 示例
eclipse的jar包配置 eclipse中貌似用不了butterknife buildToolsVersion "23.0.2" defaultConfig { applica ...
随机推荐
- laravel 二维码生成器包 QrCode 的使用
在laravel中使用 QrCode 生成二维码 https://laravelacademy.org/post/2605.html 我在本机的windows下composer require 没有成 ...
- springboot mybatisPlus配置
1.pom依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="htt ...
- PTA 是否同一棵二叉搜索树(25 分)
是否同一棵二叉搜索树(25 分) 给定一个插入序列就可以唯一确定一棵二叉搜索树.然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到.例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始 ...
- C++11 变量和函数的链接性
在全局变量前添加const或者static,则该变量链接性为内部,即文件内有效.可以使用extern声明为外部. 如果要让函数的链接性为内部,则函数声明和定义都应使用static关键字. 例子: te ...
- Python函数的初识
一 什么是函数 定义: 定义一个事情或者功能,等到需要用的时候直接用就可以了,那么这个定义的就是一个函数 函数 : 对代码块和功能的封装和定义 函数定义的格式: def 函数名() ...
- leetcode427
本题不会做,从网上找到了python3的解法,记录如下. class Solution: def construct(self, grid): def dfs(x, y, l): if l == 1: ...
- Holding Bin-Laden Captive!
We all know that Bin-Laden is a notorious terrorist, and he has disappeared for a long time. But rec ...
- IE回车的一个怪异行为
IE中在input中回车相当于提交form,会从dom中找最近的button标签触发click事件 <!DOCTYPE html> <html> <head> &l ...
- uboot重定位代码分析(转)
概述 重定位(relocate)代码将BootLoader自身由Flash复制到SDRAM,以便跳转到SDRAM执行.之所以需要进行重定位是因为在Flash中执行速度比较慢,而系统复位后总是从0x00 ...
- android解析xml文件的方式
android解析xml文件的方式 作者:东子哥 ,发布于2012-11-26,来源:博客园 在androd手机中处理xml数据时很常见的事情,通常在不同平台传输数据的时候,我们就可能使用xm ...