前言网络编程在Android开发中必不可少,不上网的app根本就没有利润可言。废话不多说,来看看Android中网络请求的演变:HttpURLConnection、ApacheHTTPClient、Volley到现在的OKHttp,可以说天外有天,人外有人。为什么OKHttp如此受欢迎,相信下面的介绍会告诉你答案。OKHttp介绍首先给出OKHttp的项目地址:https://github.com/square/okhttpAndroid为我们提供了两种HTTP交互方式:HttpURLConnection和ApacheHTTPClient,虽然都支持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。如果你使用ApacheHttpClient,OkHttp也提供了相应的okhttp-apache模块。从上面的简单介绍我们可以知道,虽然编程不是很简单,但是OKHttp内部的一些函数可以帮助我们自动完成一些非常复杂的操作。我个人认为最大的卖点就是大大节省了用户流量。.OKHttp的基本使用1.在Gradle中引入CardView的依赖库。编译'com.squareup.okhttp:okhttp:3.8.0'2。在使用OKHttp之前,你必须先了解以下核心类及其作用。OkHttpClient客户端对象Request是OkHttp中访问的请求,Post请求需要包含RequestBodyBuilder,这是一个辅助类,用来产生对象Response,也就是OkHttp中的响应。在response中可以获取是否返回成功,返回的数据MediaType数据类型用于表示是JSONRequestBody等一系列格式的请求数据,在Post请求client.newCall(request)中使用。execute()是同步请求方法client.newCall(request).enqueue(Callbackcallback)是异步请求方法,但是Callback中的代码是在子线程中执行的,所以无法更新UI。3、OKHttp的基本使用步骤(以POST方式从服务器获取JSON数据为例)创建一个OkHttpClient对象。官方文档要求我们使用单例模式,后面封装OKHttp的时候会提到。如果是post请求,需要通过FormEncodingBuilder创建一个RequestBody对象,并指定post需要传入的参数。不使用获取请求。创建一个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线程。确实,如果要操作控件,还是需要使用handlers等。().url(Constants.URL_BANNER).post(body).build();client.newCall(request).enqueue(newCallback(){@OverridepublicvoidonFailure(Requestrequest,IOExceptione){}@OverridepublicvoidonResponse(Responseresponse)throwsIOException{if(response.isSuccessful()){android.os.Messagemsg=newMessage();msg.what=1;msg.obj=response.body().string();mHandler.sendMessage(msg);}}});这里只是一个简单的post请求,介绍从服务器获取数据,至于get请求只是去掉RequestBody对象即可。至于如何向服务器提交数据,在熟悉了上面的基本用法后,可以参考官方的WIKI(GitHub的介绍文档)。OKHttp的简单封装回过头来看上面的代码,想象一下,如果每次请求都写那么多重复的代码,会严重降低开发效率,所以需要对OKHttp进行封装。封装代码是我们大多数面向对象程序员的基本素质,减少重复代码,降低维护难度和成本。OKHttp也已经在GitHub上打包了,叫做OKHttpUtils。不过这里我们自己动手,一起来学习如何打包吧。具体需要注意的地方如下:1、首先,OKHttp官方要求我们在单例模式下使用OKHttpClient类,所以我们自定义一个OKHttpHelper类,使用单例模式。2.对get和post方法进行封装,主要思路是提取公共代码,比如从代码中提取request方法。3.公开一些静态方法,包括get和post方法。4.回调基类,封装了OKHttp的回调。这个类里面有一个type,是一个封装,方便在回调中使用Gson解析JSON。使用Callback时,只需要在泛型中传入Data或List之类的东西,就可以方便的使用JSON了。5、由于原来的callback不在主线程中,所以我们需要使用Handler将callback放到主线程中。其余的可以参考代码,有详细的注释。/***这个类用来辅助OKHttp*/publicclassOkHttpHelper{/***单例模式下使用OkHttpClient*/privatestaticOkHttpHelpermOkHttpHelperInstance;privatestaticOkHttpClientmClientInstance;privateHandlermHandler;privateGsonmGson;/***单例模式,私有构造函数,构造函数内部一些初始化*/privateOkHttpHelper(){mClientInstance=newOkHttpClient();mClientInstance.setConnectTimeout(10,TimeUnit.SECONDS);mClientInstance.setReadTimeout(10,TimeUnit.SECONDS);mClientInstance.setWriteTimeout(30,TimeUnit.SECONDS);mGson=newGson();mHandler=newHandler(Looper.getMainLooper());}/***获取实例**@return*/publicstaticOkHttpHelpergetinstance(){if(mOkHttpHelperInstance==null){synchronized(OkHttpHelper.class){if(mOkHttpHelperInstance==null){mOkHttpHelperInstance=newOkHttpHelper();}}}returnmOkHttpHelperInstance;}/***封装了一个request方法,post和get方法都会用到它*/publicvoidrequest(finalRequestrequest,finalBaseCallbackcallback){//请求前的东西,比如弹出对话框等callback.onRequestBefore();mClientInstance.newCall(request).enqueue(newCallback(){@OverridepublicvoidonFailure(Requestrequest,IOExceptione){//返回失败回调Failure(request,callback,e);}@OverridepublicvoidonResponse(Responseresponse)throwsIOException{if(response.isSuccessful()){//返回成功回调StringresString=response.body().string();if(callback.mType==String.class){//如果我们需要返回String类型callbackSuccess(response,resString,callback);}else{//如果返回类型是其他类型,使用Gson来解析try{Objecto=mGson.fromJson(resString,callback.mType);callbackSuccess(response,o,callback);}catch(JsonParseExceptione){e.printStackTrace();callbackError(response,callback,e);}}}else{//返回错误callbackError(response,callback,null);}}});}/***在主线程中执行的回调**@paramresponse*@paramresString*@paramcallback*/privatevoidcallbackSuccess(finalResponseresponse,finalObjecto,finalBaseCallbackcallback){mHandler.post(newRunnable(){@Overridepublicvoidrun(){callback.onSuccess(response,o);}});}/***在主线程中执行的回调*@paramresponse*@paramcallback*@parame*/privatevoidcallbackError(finalResponseresponse,finalBaseCallbackcallback,finalExceptione){mHandler.post(newRunnable(){@Overridepublicvoidrun(){callback.onError(response,response.code(),e);}});}/***在主线程中执行的回调*@paramrequest*@paramcallback*@parame*/privatevoidcallbackFailure(finalRequestrequest,finalBaseCallbackcallback,finalExceptione){mHandler.post(newRunnable(){@Overridepublicvoidrun(){callback.onFailure(request,e);}});}/***公共获取方法**@paramurl*@paramcallback*/publicvoidget(Stringurl,BaseCallbackcallback){Requestrequest=buildRequest(url,null,HttpMethodType.GET);request(request,callback);}/***公开发布方法**@paramurl*@paramparams*@paramcallback*/publicvoidpost(Stringurl,Map>(){@OverridepublicvoidonRequestBefore(){}@OverridepublicvoidonFailure(Requestrequest,Exceptione){}@OverridepublicvoidonSuccessonListse(响应>横幅){initBanners(横幅);}@OverridepublicvoidonError(Responseresponse,terrorCode,Exceptione){}});是不是觉得封装后OKHttp的使用变得很简单,这就是封装的力量,好了今天的笔记就到这里了。PS:这里只介绍OKHttp的get和post的使用,其余的使用,比如文件下载上传,以及相应的代码打包,请自行完成~(≧▽≦)/~啦啦啦。全文有BaseCallback和OkHttpHelper的代码,欢迎阅读原文。
