Android之网络请求okhttp使用和封装

1:Android中网络请求的进化

Android开发中网络编程是必不可少的,不接入互联网的APP就没有盈利可言。废话不多说了,下面请看Android中网络请求的进化图:

2:OKHttp的简介

Android为我们提供了两种HTTP交互的方式: HttpURLConnection 和 Apache HTTP Client,虽然两者都支持HTTPS,流的上传和下载,配置超时,IPv6和连接池,已足够满足我们各种HTTP请求的需求。但更高效的使用HTTP可以让您的应用运行更快、更节省流量。而OkHttp库就是为此而生。 OkHttp是一个高效的HTTP库:1.支持 SPDY ,共享同一个Socket来处理同一个服务器的所有请求2.如果SPDY不可用,则通过连接池来减少请求延时3.无缝的支持GZIP来减少数据流量4. 缓存响应数据来减少重复的网络请求

· 一般的get请求

· 一般的post请求

· 基于Http的文件上传

· 文件下载

· 加载图片

· 支持请求回调,直接返回对象、对象集合

· 支持session的保持

OkHttp会从很多常用的连接问题中自动恢复。如果您的服务器配置了多个IP地址,当第一个IP连接失败的时候,会自动尝试下一个IP。OkHttp还处理了代理服务器问题和SSL握手失败问题。(并发) 使用 OkHttp 无需重写您程序中的网络代码。OkHttp实现了几乎和java.net.HttpURLConnection一样的API。如果您用了 Apache HttpClient,则OkHttp也提供了一个对应的okhttp-apache 模块。 从上面的简单介绍中可以知道,虽然在编程上面并不会简洁很多,但是OKHttp内部的一些功能能够帮助我们自动完成一些很复杂的操作,笔者个人认为最大的卖点就是大大节省用户的流量。

3:Okhttp使用

3.1首先我们在Android studio 项目的libs下面引入三个包

这三个在下面使用的时候都有用到

3.2在AndroidManifest.xml中引入网络相关权限

<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />        

3.3 在build.gradle引入包

implementation files(libs/fastjson-1.1.45.android.jar) implementation files(libs/x-2.6.14-src-1.4-modify.jar) implementation files(libs/xutils-3.3.34.jar) implementation com.squareup.okhttp:okhttp:2.5.0 implementation com.google.code.gson:gson:2.3.1 implementation com.github.d-max:spots-dialog:0.4@aar

3.4 Okhttp封装

A:BaseCallback类

import com.google.gson.internal.$Gson$Types; import com.squareup.okhttp.Request; import com.squareup.okhttp.Response; import java.io.IOException; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; public abstract class BaseCallback <T> { public Type mType; 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]); } public BaseCallback() { mType = getSuperclassTypeParameter(getClass()); } publicabstract void onBeforeRequest(Request request); public abstractvoid onFailure(Request request, Exception e) ; /** *请求成功时调用此方法 * @param response */ public abstractvoid onResponse(Response response); /** * * 状态码大于200,小于300 时调用此方法 * @param response * @param t * @throws IOException */ public abstract void onSuccess(Response response,T t) ; /** * 状态码400,404,403,500等时调用此方法 * @param response * @param code * @param e */ public abstract void onError(Response response, int code,Exception e) ; }

B OkHttpHelper类

public class OkHttpHelper { public static final String TAG="OkHttpHelper"; privatestaticOkHttpHelper mInstance; private OkHttpClient mHttpClient; private Gson mGson; private Handler mHandler; static { mInstance = new OkHttpHelper(); } private OkHttpHelper(){ mHttpClient = new OkHttpClient(); mHttpClient.setConnectTimeout(10, TimeUnit.SECONDS); mHttpClient.setReadTimeout(10,TimeUnit.SECONDS); mHttpClient.setWriteTimeout(30,TimeUnit.SECONDS); mGson = new Gson(); mHandler = new Handler(Looper.getMainLooper()); }; public staticOkHttpHelper getInstance(){ returnmInstance; } public void get(String url,BaseCallback callback){ Request request = buildGetRequest(url); request(request,callback); } public void post(String url,Map<String,String> param, BaseCallback callback){ Request request = buildPostRequest(url,param); request(request,callback); } publicvoid request(final Request request,finalBaseCallback callback){ callback.onBeforeRequest(request); mHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Request request, IOException e) { callback.onFailure(request,e); } @Override public void onResponse(Response response) throws IOException { callback.onResponse(response); if(response.isSuccessful()) { String resultStr = response.body().string(); Log.d(TAG, "result=" + resultStr); if (callback.mType == String.class){ callbackSuccess(callback,response,resultStr); } else { try { Object obj = mGson.fromJson(resultStr, callback.mType); callbackSuccess(callback,response,obj); } catch (com.google.gson.JsonParseException e){ // Json解析的错误 callback.onError(response,response.code(),e); } } } else { callbackError(callback,response,null); } } }); } private void callbackSuccess(finalBaseCallback callback , final Response response, final Object obj ){ mHandler.post(new Runnable() { @Override public void run() { callback.onSuccess(response, obj); } }); } private void callbackError(finalBaseCallback callback , final Response response, final Exception e ){ mHandler.post(new Runnable() { @Override public void run() { callback.onError(response,response.code(),e); } }); } privateRequest buildPostRequest(String url,Map<String,String> params){ returnbuildRequest(url, HttpMethodType.POST,params); } privateRequest buildGetRequest(String url){ returnbuildRequest(url, HttpMethodType.GET,null); } privateRequest buildRequest(String url,HttpMethodType methodType,Map<String,String> params){ Request.Builder builder = new Request.Builder() .url(url); if (methodType == HttpMethodType.POST){ RequestBody body = builderFormData(params); builder.post(body); } else if(methodType == HttpMethodType.GET){ builder.get(); } return builder.build(); } private RequestBody builderFormData(Map<String,String> params){ FormEncodingBuilder builder = new FormEncodingBuilder(); if(params !=null){ for (Map.Entry<String,String> entry :params.entrySet() ){ builder.add(entry.getKey(),entry.getValue()); } } returnbuilder.build(); } enumHttpMethodType{ GET, POST, } }

3.5使用示例

private OkHttpHelper httpHelper = OkHttpHelper.getInstance(); String url =":8081/course_api/banner/query?type=1"; httpHelper.get(url, new BaseCallback<List<HomeCampaign>>() { @Override public void onBeforeRequest(Request request) { } @Override public void onFailure(Request request, Exception e) { } @Override public void onResponse(Response response) { } @Override public void onSuccess(Response response, List<HomeCampaign> homeCampaigns) { //initData(homeCampaigns); } @Override public void onError(Response response, int code, Exception e) { } });

数据类HomeCampaign

package com.afc.takeawaymonitor.model; public class HomeCampaign { private int id; private String name; private String imgUrl; private String type; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getImgUrl() { return imgUrl; } public void setImgUrl(String imgUrl) { this.imgUrl = imgUrl; } public String getType() { return type; } public void setType(String type) { this.type = type; } }