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

Android okHttp网络请求之Get/Post请求

2017-09-04 16:16 916 查看
博客园

新随笔

管理

随笔-126  文章-0  评论-254 

Android okHttp网络请求之Get/Post请求

   前言:

      之前项目中一直使用的Xutils开源框架,从xutils 2.1.5版本使用到最近的xutils 3.0,使用起来也是蛮方便的,只不过最近想着完善一下app中使用的开源框架,由于Xutils里面包含的东西相对来说比较杂,有数据库、图片缓存、注解、网络请求等等,秉着一个开源库只处理一件事的想法,决定逐步替换到Xutils,上网搜了一下比较好的开源框架,就找到了okHttp、volley、android-async-http等比较推荐的开源网络请求,该如何选择呢?

     okHttp相关文章地址:

Android okHttp网络请求之Get/Post请求
Android okHttp网络请求之文件上传下载
Android okHttp网络请求之Json解析
Android okHttp网络请求之缓存控制Cache-Control
Android okHttp网络请求之Retrofit+Okhttp组合

   okHttp、volley、android-async-http对比:

volley是一个简单的异步http库,仅此而已。缺点是不支持同步,这点会限制开发模式;不能post大数据,所以不适合用来上传文件
android-async-http。与volley一样是异步网络库,但volley是封装的httpUrlConnection,它是封装的httpClient,而android平台不推荐用HttpClient了,所以这个库已经不适合android平台了。
okhttp是高性能的http库,支持同步、异步,而且实现了spdy、http2、websocket协议,api很简洁易用,和volley一样实现了http协议的缓存。

   okHttp介绍:

      通过上面的对比说明,让你不得不做出明智的选择,OkHttp是一个相对成熟的解决方案,据说Android4.4的源码中可以看到HttpURLConnection已经替换成OkHttp实现了,所以决定选择采用okhttp。

      官网地址:http://square.github.io/okhttp/

      官方API地址:http://m.blog.csdn.net/article/details?id=50747352

      github源码地址:https://github.com/square/okhttp

   okHttp主要类:

       1.)OkHttpClient.java

       2.)Request.java

       3.)Call.java

       4.)RequestBody.java

       5.)Response.java

   okHttp使用:

  1.)添加引用 build.gradle添加如下    

compile 'com.squareup.okhttp3:okhttp:3.2.0'


 2.)创建一个RequestManager类接下来以项目中用来的实战为例 
     RequestManager.java 全局属性解说

private static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/x-www-form-urlencoded; charset=utf-8");//mdiatype 这个需要和服务端保持一致
private static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");//mdiatype 这个需要和服务端保持一致
private static final String TAG = RequestManager.class.getSimpleName();
private static final String BASE_URL = "http://xxx.com/openapi";//请求接口根地址
private static volatile RequestManager mInstance;//单利引用
public static final int TYPE_GET = 0;//get请求
public static final int TYPE_POST_JSON = 1;//post请求参数为json
public static final int TYPE_POST_FORM = 2;//post请求参数为表单
private OkHttpClient mOkHttpClient;//okHttpClient 实例
private Handler okHttpHandler;//全局处理子线程和M主线程通信


     RequestManager.java 构造函数

/**
* 初始化RequestManager
*/
public RequestManager(Context context) {
//初始化OkHttpClient
mOkHttpClient = new OkHttpClient().newBuilder()
.connectTimeout(10, TimeUnit.SECONDS)//设置超时时间
.readTimeout(10, TimeUnit.SECONDS)//设置读取超时时间
.writeTimeout(10, TimeUnit.SECONDS)//设置写入超时时间
.build();
//初始化Handler
okHttpHandler = new Handler(context.getMainLooper());
}


   RequestManager.java 获取单利引用 这里用到了双重检查锁实现单例

/**
* 获取单例引用
*
* @return
*/
public static RequestManager getInstance(Context context) {
RequestManager inst = mInstance;
if (inst == null) {
synchronized (RequestManager.class) {
inst = mInstance;
if (inst == null) {
inst = new RequestManager(context.getApplicationContext());
mInstance = inst;
}
}
}
return inst;
}


 3.)实现okHttp同步请求
     同步请求统一入口

/**
*  okHttp同步请求统一入口
* @param actionUrl  接口地址
* @param requestType 请求类型
* @param paramsMap   请求参数
*/
public void requestSyn(String actionUrl, int requestType, HashMap<String, String> paramsMap) {
switch (requestType) {
case TYPE_GET:
requestGetBySyn(actionUrl, paramsMap);
break;
case TYPE_POST_JSON:
requestPostBySyn(actionUrl, paramsMap);
break;
case TYPE_POST_FORM:
requestPostBySynWithForm(actionUrl, paramsMap);
break;
}
}


okHttp get同步请求


    /**
*okHttp get同步请求
* @param actionUrl 接口地址
* @param paramsMap 请求参数
*/
private void requestGetBySyn(String actionUrl, HashMap<String, String> paramsMap) {
StringBuilder tempParams = new StringBuilder();
try {
//处理参数
int pos = 0;
for (String key : paramsMap.keySet()) {
if (pos > 0) {
tempParams.append("&");
}
//对参数进行URLEncoder
tempParams.append(String.format("%s=%s", key, URLEncoder.encode(paramsMap.get(key), "utf-8")));
pos++;
}
//补全请求地址
String requestUrl = String.format("%s/%s?%s", BASE_URL, actionUrl, tempParams.toString());
//创建一个请求
Request request = addHeaders().url(requestUrl).build();
//创建一个Call
final Call call = mOkHttpClient.newCall(request);
//执行请求
final Response response = call.execute();
response.body().string();
} catch (Exception e) {
Log.e(TAG, e.toString());
}
}


okHttp post同步请求


/**
* okHttp post同步请求
* @param actionUrl  接口地址
* @param paramsMap   请求参数
*/
private void requestPostBySyn(String actionUrl, HashMap<String, String> paramsMap) {
try {
//处理参数
StringBuilder tempParams = new StringBuilder();
int pos = 0;
for (String key : paramsMap.keySet()) {
if (pos > 0) {
tempParams.append("&");
}
tempParams.append(String.format("%s=%s", key, URLEncoder.encode(paramsMap.get(key), "utf-8")));
pos++;
}
//补全请求地址
String requestUrl = String.format("%s/%s", BASE_URL, actionUrl);
//生成参数
String params = tempParams.toString();
//创建一个请求实体对象 RequestBody
RequestBody body = RequestBody.create(MEDIA_TYPE_JSON, params);
//创建一个请求
final Request request = addHeaders().url(requestUrl).post(body).build();
//创建一个Call
final Call call = mOkHttpClient.newCall(request);
//执行请求
Response response = call.execute();
//请求执行成功
if (response.isSuccessful()) {
//获取返回数据 可以是String,bytes ,byteStream
Log.e(TAG, "response ----->" + response.body().string());
}
} catch (Exception e) {
Log.e(TAG, e.toString());
}
}


okHttp post同步请求表单提交


/**
* okHttp post同步请求表单提交
* @param actionUrl 接口地址
* @param paramsMap 请求参数
*/
private void requestPostBySynWithForm(String actionUrl, HashMap<String, String> paramsMap) {
try {
//创建一个FormBody.Builder
FormBody.Builder builder = new FormBody.Builder();
for (String key : paramsMap.keySet()) {
//追加表单信息
builder.add(key, paramsMap.get(key));
}
//生成表单实体对象
RequestBody formBody = builder.build();
//补全请求地址
String requestUrl = String.format("%s/%s", BASE_URL, actionUrl);
//创建一个请求
final Request request = addHeaders().url(requestUrl).post(formBody).build();
//创建一个Call
final Call call = mOkHttpClient.newCall(request);
//执行请求
Response response = call.execute();
if (response.isSuccessful()) {
Log.e(TAG, "response ----->" + response.body().string());
}
} catch (Exception e) {
Log.e(TAG, e.toString());
}
}


 4.)实现okHttp异步请求
   异步请求统一入口

/**
* okHttp异步请求统一入口
* @param actionUrl   接口地址
* @param requestType 请求类型
* @param paramsMap   请求参数
* @param callBack 请求返回数据回调
* @param <T> 数据泛型
**/
public <T> Call requestAsyn(String actionUrl, int requestType, HashMap<String, String> paramsMap, ReqCallBack<T> callBack) {
Call call = null;
switch (requestType) {
case TYPE_GET:
call = requestGetByAsyn(actionUrl, paramsMap, callBack);
break;
case TYPE_POST_JSON:
call = requestPostByAsyn(actionUrl, paramsMap, callBack);
break;
case TYPE_POST_FORM:
call = requestPostByAsynWithForm(actionUrl, paramsMap, callBack);
break;
}
return call;
}


okHttp get异步请求


/**
* okHttp get异步请求
* @param actionUrl 接口地址
* @param paramsMap 请求参数
* @param callBack 请求返回数据回调
* @param <T> 数据泛型
* @return
*/
private <T> Call requestGetByAsyn(String actionUrl, HashMap<String, String> paramsMap, final ReqCallBack<T> callBack) {
StringBuilder tempParams = new StringBuilder();
try {
int pos = 0;
for (String key : paramsMap.keySet()) {
if (pos > 0) {
tempParams.append("&");
}
tempParams.append(String.format("%s=%s", key, URLEncoder.encode(paramsMap.get(key), "utf-8")));
pos++;
}
String requestUrl = String.format("%s/%s?%s", BASE_URL, actionUrl, tempParams.toString());
final Request request = addHeaders().url(requestUrl).build();
final Call call = mOkHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
failedCallBack("访问失败", callBack);
Log.e(TAG, e.toString());
}

@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
String string = response.body().string();
Log.e(TAG, "response ----->" + string);
successCallBack((T) string, callBack);
} else {
failedCallBack("服务器错误", callBack);
}
}
});
return call;
} catch (Exception e) {
Log.e(TAG, e.toString());
}
return null;
}


okHttp post异步请求


/**
* okHttp post异步请求
* @param actionUrl 接口地址
* @param paramsMap 请求参数
* @param callBack 请求返回数据回调
* @param <T> 数据泛型
* @return
*/
private <T> Call requestPostByAsyn(String actionUrl, HashMap<String, String> paramsMap, final ReqCallBack<T> callBack) {
try {
StringBuilder tempParams = new StringBuilder();
int pos = 0;
for (String key : paramsMap.keySet()) {
if (pos > 0) {
tempParams.append("&");
}
tempParams.append(String.format("%s=%s", key, URLEncoder.encode(paramsMap.get(key), "utf-8")));
pos++;
}
String params = tempParams.toString();
RequestBody body = RequestBody.create(MEDIA_TYPE_JSON, params);
String requestUrl = String.format("%s/%s", BASE_URL, actionUrl);
final Request request = addHeaders().url(requestUrl).post(body).build();
final Call call = mOkHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
failedCallBack("访问失败", callBack);
Log.e(TAG, e.toString());
}

@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
String string = response.body().string();
Log.e(TAG, "response ----->" + string);
successCallBack((T) string, callBack);
} else {
failedCallBack("服务器错误", callBack);
}
}
});
return call;
} catch (Exception e) {
Log.e(TAG, e.toString());
}
return null;
}


okHttp post异步请求表单提交


/**
* okHttp post异步请求表单提交
* @param actionUrl 接口地址
* @param paramsMap 请求参数
* @param callBack 请求返回数据回调
* @param <T> 数据泛型
* @return
*/
private <T> Call requestPostByAsynWithForm(String actionUrl, HashMap<String, String> paramsMap, final ReqCallBack<T> callBack) {
try {
FormBody.Builder builder = new FormBody.Builder();
for (String key : paramsMap.keySet()) {
builder.add(key, paramsMap.get(key));
}
RequestBody formBody = builder.build();
String requestUrl = String.format("%s/%s", BASE_URL, actionUrl);
final Request request = addHeaders().url(requestUrl).post(formBody).build();
final Call call = mOkHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
failedCallBack("访问失败", callBack);
Log.e(TAG, e.toString());
}

@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
String string = response.body().string();
Log.e(TAG, "response ----->" + string);
successCallBack((T) string, callBack);
} else {
failedCallBack("服务器错误", callBack);
}
}
});
return call;
} catch (Exception e) {
Log.e(TAG, e.toString());
}
return null;
}


接口ReqCallBack.java实现

public interface ReqCallBack<T> {
/**
* 响应成功
*/
void onReqSuccess(T result);

/**
* 响应失败
*/
void onReqFailed(String errorMsg);
}


5.)如何添加请求头

/**
* 统一为请求添加头信息
* @return
*/
private Request.Builder addHeaders() {
Request.Builder builder = new Request.Builder()
.addHeader("Connection", "keep-alive")
.addHeader("platform", "2")
.addHeader("phoneModel", Build.MODEL)
.addHeader("systemVersion", Build.VERSION.RELEASE)
.addHeader("appVersion", "3.2.0");
return builder;
}


 6.)成功与失败 回调处理

   成功回调处理

/**
* 统一同意处理成功信息
* @param result
* @param callBack
* @param <T>
*/
private <T> void successCallBack(final T result, final ReqCallBack<T> callBack) {
okHttpHandler.post(new Runnable() {
@Override
public void run() {
if (callBack != null) {
callBack.onReqSuccess(result);
}
}
});
}


失败回调处理

/**
* 统一处理失败信息
* @param errorMsg
* @param callBack
* @param <T>
*/
private <T> void failedCallBack(final String errorMsg, final ReqCallBack<T> callBack) {
okHttpHandler.post(new Runnable() {
@Override
public void run() {
if (callBack != null) {
callBack.onReqFailed(errorMsg);
}
}
});
}


小结:基于上述基本上可以实现http之间的网络通讯,接下来我们来研究如何搞定文件的上传和下载。具体实现参考(http://www.cnblogs.com/whoislcj/p/5529827.html)

 

   

       

好文要顶
关注我 收藏该文








总李写代码
关注 - 0
粉丝 - 265

+加关注

4
0

«
上一篇:Android探索之HttpURLConnection网络请求
»
下一篇:Android okHttp网络请求之文件上传下载

posted @ 2016-05-25 11:42
总李写代码 阅读(34026) 评论(1)

编辑
收藏

评论列表

  
#1楼34420302016/5/30
14:53:05 2016-05-30 14:53
frank.sunny
 

写的很详细,受教了,谢谢啊
支持(0)反对(0)

刷新评论刷新页面返回顶部

注册用户登录后才能发表评论,请
登录 或 注册,访问网站首页。

【推荐】50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
【推荐】腾讯云域名+云解析 限时折扣抓紧抢购
【推荐】可嵌入您系统的“在线Excel”!SpreadJS 纯前端表格控件
【推荐】阿里云“全民云计算”优惠升级





最新IT新闻:

· 三星洗衣机打算用 AI 洗衣服,但情况可能你想象的不一样

· 百度起诉杭州任性智能科技流量劫持:索赔36682元

· 黄晓明投的明星衣橱被爆长期拖欠薪资 员工已求助法律解决

· 谷歌和Verily发布新研究,通过AI分析视网膜图像可检测心脏病

· 爱用微信转账的人注意 转账截图不算证据

»
更多新闻...





最新知识库文章:
·
做到这一点,你也可以成为优秀的程序员

· 写给立志做码农的大学生

· 架构腐化之谜

· 学会

最新随笔

1. Android学习探索之App多渠道打包及动态添加修改资源属性
2. Android学习探索之运用MVP设计模式实现项目解耦
3. Android注解使用之Dagger2实现项目依赖关系解耦
4. Android学习探索之本地原生渲染 LaTeX数据公式
5. Java数据结构之Set学习总结
6. Java数据结构之Map学习总结
7. Java数据结构之LinkedList、ArrayList的效率分析
8. Android业务组件化之Gradle和Sonatype Nexus搭建私有maven仓库
9. Android UI体验之全屏沉浸式透明状态栏效果
10. Android注解使用之通过annotationProcessor注解生成代码实现自己的ButterKnife框架

随笔分类(126)

Android UI体验(1)

Android动画效果(5)

Android混合开发(3)

Android加密解密(7)

Android权限管理(3)

Android使用注解(5)

Android数据存储(5)

Android四大组件(4)

Android图片缓存(4)

Android网络请求(6)

Android线程管理(5)

Android消息传递(4)

Android性能优化(5)

Android学习探索(4)

Android业务组件化(4)

Android音频视频(5)

Android知识小结(3)

Android自定义控件(4)

Hybrid App开发(10)

IOS缓存管理(2)

IOS控件布局(5)

IOS任务管理(3)

IOS数据存储(6)

IOS网络请求(2)

IOS学习总结(6)

Java日常总结(3)

Java设计模式(6)

Java数据结构(3)

React Native开发

工作随笔(3)

积分与排名

积分 - 238656
排名 - 797

最新评论

1. Re:Android混合开发之WebViewJavascriptBridge实现JS与java安全交互
给出对应的github的地址上传demo正好我们都去关注一下
--全球顶尖卧底
2. Re:Android混合开发之WebViewJavascriptBridge实现JS与java安全交互
看了一些你的文章今天 个人觉得吧 文章还是不错 但是有个缺点 就是现在很多看文章的人出现的一个通病 就是光看文章感觉挺有道理 但是叫自己写的话就会出现难度 不知道博主能否分享在写文......
--全球顶尖卧底
3. Re:Android图片缓存之初识Glide
@全球顶尖卧底谢谢支持...
--总李写代码

阅读排行榜

1. Android图片缓存之初识Glide(40819)
2. Android okHttp网络请求之Get/Post请求(34024)
3. Android数据存储之GreenDao 3.0 详解(30714)
4. Android消息传递之EventBus 3.0使用详解(30333)
5. Android okHttp网络请求之文件上传下载(27048)
6. Android混合开发之WebView与Javascript交互(24476)
7. Android动画效果之Frame Animation(逐帧动画)(20035)
8. Android自定义控件之自定义组合控件(19679)
9. Android图片缓存之Glide进阶(18687)
10. Android业务组件化之URL Scheme使用(16670)
11. Android自定义控件之基本原理(15876)
12. Android自定义控件之自定义属性(14907)
13. Android数据加密之MD5加密(14030)
14. Android数据加密之Aes加密(13735)
15. Java学习之注解Annotation实现原理(13095)
16. Android数据加密之Base64编码算法(13073)
17. Android混合开发之WebView使用总结(11780)
18. Android探索之HttpURLConnection网络请求(11281)
19. Android图片缓存之Bitmap详解(10850)
20. Android数据存储之Android 6.0运行时权限下文件存储的思考(10466)

推荐排行榜

1. Android业务组件化之现状分析与探讨(7)
2. Android业务组件化之URL Scheme使用(6)
3. Android自定义控件之自定义组合控件(6)
4. Android自定义控件之基本原理(6)
5. Android数据存储之GreenDao 3.0 详解(5)
6. Android注解使用之ButterKnife 8.0注解使用介绍(5)
7. Android图片缓存之初识Glide(5)
8. Android okHttp网络请求之Get/Post请求(4)
9. Android性能优化之利用LeakCanary检测内存泄漏及解决办法(4)
10. Android混合开发之WebViewJavascriptBridge实现JS与java安全交互(4)
11. Android UI体验之全屏沉浸式透明状态栏效果(3)
12. IOS缓存管理之YYCache使用(3)
13. Android线程管理之ThreadPoolExecutor自定义线程池(3)
14. Android消息传递之EventBus 3.0使用详解(3)
15. Java学习之注解Annotation实现原理(3)
16. Android混合开发之WebView使用总结(3)
17. Java学习之反射机制及应用场景(3)
18. Android动画效果之初识Property Animation(属性动画)(3)
19. Android动画效果之Frame Animation(逐帧动画)(3)
20. Android动画效果之Tween Animation(补间动画)(3)

Copyright ©2017 总李写代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: