这篇文章主要为大家展示了“OkHttp怎么用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“OkHttp怎么用”这篇文章吧。
创新互联自成立以来,一直致力于为企业提供从网站策划、网站设计、做网站、成都网站设计、电子商务、网站推广、网站优化到为企业提供个性化软件开发等基于互联网的全面整合营销服务。公司拥有丰富的网站建设和互联网应用系统开发管理经验、成熟的应用系统解决方案、优秀的网站开发工程师团队及专业的网站设计师团队。
前言
先看Android中网络请求的进化图:
HttpURLConnection,Apache HTTP Client,Volley到现在的OKHttp,可谓天外有天,人外有人。为什么OKHttp会这么火呢,相信下面的介绍会告诉你答案。
OKHttp的简介
首先,给出OKHttp的项目地址:https://github.com/square/okhttp
Android为我们提供了两种HTTP交互的方式: HttpURLConnection 和 Apache HTTP Client,虽然两者都支持HTTPS,流的上传和下载,配置超时,IPv6和连接池,已足够满足我们各种HTTP请求的需求。但更高效的使用HTTP可以让您的应用运行更快、更节省流量。而OkHttp库就是为此而生。 OkHttp是一个高效的HTTP库:
1.支持 SPDY ,共享同一个Socket来处理同一个服务器的所有请求
2.如果SPDY不可用,则通过连接池来减少请求延时
3.无缝的支持GZIP来减少数据流量
1.缓存响应数据来减少重复的网络请求
2.一般的get请求
3.一般的post请求
4.基于Http的文件上传
5.文件下载
6.加载图片
7.支持请求回调,直接返回对象、对象集合
8.支持session的保持
OkHttp会从很多常用的连接问题中自动恢复。如果您的服务器配置了多个IP地址,当***个IP连接失败的时候,会自动尝试下一个IP。OkHttp还处理了代理服务器问题和SSL握手失败问题。(并发) 使用 OkHttp 无需重写您程序中的网络代码。OkHttp实现了几乎和java.net.HttpURLConnection一样的API。如果您用了 Apache HttpClient,则OkHttp也提供了一个对应的okhttp-apache 模块。 从上面的简单介绍中可以知道,虽然在编程上面并不会简洁很多,但是OKHttp内部的一些功能能够帮助我们自动完成一些很复杂的操作,笔者个人认为***的卖点就是大大节省用户的流量。
OKHttp的基本使用
1、在Gradle中引入CardView的依赖库。
compile 'com.squareup.okhttp:okhttp:3.8.0'
2、OKHttp在使用之前,首先要了解下面几个比较核心的类以及它的功能。
OkHttpClient 客户端对象
Request是OkHttp中访问的请求,Post请求中需要包含RequestBody
Builder是辅助类,用于生产对象
Response即OkHttp中的响应,响应中可以得到返回是否成功,返回数据
MediaType 数据类型,用来表明是JSON等一系列格式
RequestBody 请求数据,在Post请求中用到
client.newCall(request).execute()是同步的请求方法
client.newCall(request).enqueue(Callback callBack)是异步的请求方法,但是Callback里面的代码是执行在子线程的,因此不能更新UI。
3、OKHttp的基本使用步骤(以POST方式从服务器取JSON数据为例)
创建OkHttpClient对象,官方文档要求我们***使用单例模式,在后文对OKHttp进行封装的时候会提到。
如果是post请求的话,需要通过FormEncodingBuilder创建RequestBody对象,指定需要post传进去的参数。get请求则不用。
创建Request对象,这个对象是请求对象,需要指定URL。post请求的时候需要指定RequestBody对象,get请求则不用。
调用OkHttpClient的newCall方法,把Request对象传进去,然后执行execute或者enqueue方法,两者的区别在上文已提到。在CallBack中的onResponse方法就可以做你需要做的事。onResponse回调的参数是response,一般情况下,比如我们希望获得返回的字符串,可以通过response.body().string()获取;如果希望获得返回的二进制字节数组,则调用response.body().bytes();如果你想拿到返回的inputStream,则调用response.body().byteStream()看到这,你可能会奇怪,竟然还能拿到返回的inputStream,看到这个最起码能意识到一点,这里支持大文件下载,有inputStream我们就可以通过IO的方式写文件。不过也说明一个问题,这个onResponse执行的线程并不是UI线程。的确是的,如果你希望操作控件,还是需要使用handler等。
OkHttpClient client = new OkHttpClient(); RequestBody body = new FormEncodingBuilder() .add("type", "1") .build(); Request request = new Request.Builder() .url(Constants.URL_BANNER) .post(body) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Request request, IOException e) { } @Override public void onResponse(Response response) throws IOException { if (response.isSuccessful()) { android.os.Message msg = new Message(); msg.what = 1; msg.obj = response.body().string(); mHandler.sendMessage(msg); } } });
这里只是一个简单post请求,从服务器获取数据的介绍,至于get请求只不过是去掉RequestBody对象而已。至于如何向服务器提交数据,可以在熟悉上面的基本用法之后查阅官方的WIKI(GitHub的介绍文档)。
OKHttp的简单封装
回顾上面的代码,试想一下如果每次请求都写这么多重复代码,这样会严重降低开发效率,因此需要对OKHttp进行封装。对代码进行封装是我们最为面向对象程序员的基本素养,减少重复代码,降低维护难度以及成本。
GitHub上也有对OKHttp进行过封装,叫做OKHttpUtils。不过这里我们自己动手,一起来学习一下如何进行封装。具体的注意点有下面几点:
1、首先,OKHttp官方要求我们***用单例模式去使用OKHttpClient类的,因此我们自定义一个OKHttpHelper类,并且使用单例模式。
2、对get以及post方法进行封装,主要的思想是把共同的代码抽取出来,例如代码中被抽取出来的request方法。
3、对外公开一些静态方法,包括get和post方法等。
4、Callback基类,对OKHttp的回调进行封装。这个类用里面有一个type,是方便回调中使用Gson对JSON进行解析的封装。使用Callback的时候只需要在泛型中传入类似Data 、List即可以方便地使用JSON。
5、由于原来的回调不在主线程,因此我们需要使用Handler来将回调放入主线程。
其余的可以参照代码,有详细注释。
/** * 这个类用来辅助OKHttp */public class OkHttpHelper { /** * 采用单例模式使用OkHttpClient */ private static OkHttpHelper mOkHttpHelperInstance; private static OkHttpClient mClientInstance; private Handler mHandler; private Gson mGson; /** * 单例模式,私有构造函数,构造函数里面进行一些初始化 */ private OkHttpHelper() { mClientInstance = new OkHttpClient(); mClientInstance.setConnectTimeout(10, TimeUnit.SECONDS); mClientInstance.setReadTimeout(10, TimeUnit.SECONDS); mClientInstance.setWriteTimeout(30, TimeUnit.SECONDS); mGson = new Gson(); mHandler = new Handler(Looper.getMainLooper()); } /** * 获取实例 * * @return */ public static OkHttpHelper getinstance() { if (mOkHttpHelperInstance == null) { synchronized (OkHttpHelper.class) { if (mOkHttpHelperInstance == null) { mOkHttpHelperInstance = new OkHttpHelper(); } } } return mOkHttpHelperInstance; } /** * 封装一个request方法,不管post或者get方法中都会用到 */ public void request(final Request request, final BaseCallback callback) { //在请求之前所做的事,比如弹出对话框等 callback.onRequestBefore(); mClientInstance.newCall(request).enqueue(new Callback() { @Override public void onFailure(Request request, IOException e) { //返回失败 callbackFailure(request, callback, e); } @Override public void onResponse(Response response) throws IOException { if (response.isSuccessful()) { //返回成功回调 String resString = response.body().string(); if (callback.mType == String.class) { //如果我们需要返回String类型 callbackSuccess(response, resString, callback); } else { //如果返回的是其他类型,则利用Gson去解析 try { Object o = mGson.fromJson(resString, callback.mType); callbackSuccess(response, o, callback); } catch (JsonParseException e) { e.printStackTrace(); callbackError(response, callback, e); } } } else { //返回错误 callbackError(response, callback, null); } } }); } /** * 在主线程中执行的回调 * * @param response * @param resString * @param callback */ private void callbackSuccess(final Response response, final Object o, final BaseCallback callback) { mHandler.post(new Runnable() { @Override public void run() { callback.onSuccess(response, o); } }); } /** * 在主线程中执行的回调 * @param response * @param callback * @param e */ private void callbackError(final Response response, final BaseCallback callback, final Exception e) { mHandler.post(new Runnable() { @Override public void run() { callback.onError(response, response.code(), e); } }); } /** * 在主线程中执行的回调 * @param request * @param callback * @param e */ private void callbackFailure(final Request request, final BaseCallback callback, final Exception e) { mHandler.post(new Runnable() { @Override public void run() { callback.onFailure(request, e); } }); } /** * 对外公开的get方法 * * @param url * @param callback */ public void get(String url, BaseCallback callback) { Request request = buildRequest(url, null, HttpMethodType.GET); request(request, callback); } /** * 对外公开的post方法 * * @param url * @param params * @param callback */ public void post(String url, Mapparams, BaseCallback callback) { Request request = buildRequest(url, params, HttpMethodType.POST); request(request, callback); } /** * 构建请求对象 * * @param url * @param params * @param type * @return */ private Request buildRequest(String url, Map params, HttpMethodType type) { Request.Builder builder = new Request.Builder(); builder.url(url); if (type == HttpMethodType.GET) { builder.get(); } else if (type == HttpMethodType.POST) { builder.post(buildRequestBody(params)); } return builder.build(); } /** * 通过Map的键值对构建请求对象的body * * @param params * @return */ private RequestBody buildRequestBody(Map params) { FormEncodingBuilder builder = new FormEncodingBuilder(); if (params != null) { for (Map.Entry entity : params.entrySet()) { builder.add(entity.getKey(), entity.getValue()); } } return builder.build(); } /** * 这个枚举用于指明是哪一种提交方式 */ enum HttpMethodType { GET, POST } }
回调的封装
package com.nan.cnshop.http; import com.google.gson.internal.$Gson$Types; import com.squareup.okhttp.Request; import com.squareup.okhttp.Response; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type;/** * 基本的回调 */public abstract class BaseCallback{ /** * type用于方便JSON的解析 */ public Type mType; /** * 把type转换成对应的类,这里不用看明白也行。 * * @param subclass * @return */ static Type getSuperclassTypeParameter(Class> subclass) { Type superclass = subclass.getGenericSuperclass(); if (superclass instanceof Class) { throw new RuntimeException("Missing type parameter."); } ParameterizedType parameterized = (ParameterizedType) superclass; return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]); } /** * 构造的时候获得type的class */ public BaseCallback() { mType = getSuperclassTypeParameter(getClass()); } /** * 请求之前调用 */ public abstract void onRequestBefore(); /** * 请求失败调用(网络问题) * * @param request * @param e */ public abstract void onFailure(Request request, Exception e); /** * 请求成功而且没有错误的时候调用 * * @param response * @param t */ public abstract void onSuccess(Response response, T t); /** * 请求成功但是有错误的时候调用,例如Gson解析错误等 * * @param response * @param errorCode * @param e */ public abstract void onError(Response response, int errorCode, Exception e); }
OKHttp封装之后的使用
如下面的代码所示。首先得到OkHttpHelper的单例,然后调用get方法就可以了。由于继承了Gson,因此需要在BaseCallback的泛型中传入JSON对应的数据类型,笔者这里是List
mHttpHelper=OkHttpHelper.getinstance(); mHttpHelper.get(Constants.URL_BANNER, new BaseCallback>() { @Override public void onRequestBefore() { } @Override public void onFailure(Request request, Exception e) { } @Override public void onSuccess(Response response, List
banners) { initBanners(banners); } @Override public void onError(Response response, int errorCode, Exception e) { } });
是不是觉得封装之后OKHttp的使用变得很简单呢,这就是封装的强大之处,好了今天的笔记到此为止。
以上是“OkHttp怎么用”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注创新互联行业资讯频道!