项目中okhttp网络框架的封装使用
来源:互联网 发布:js match对象 编辑:程序博客网 时间:2024/06/06 02:01
对okhttp网络框架进行封装,多种请求方式,包括图片上传,图片压缩上传,回调结果切换到主线程。使用fastjson将返回的json数据处理成对象返回。
1.工具类
/** * Created by Pan on 2017/6/26 0026 09:54 * Desc: */public class RequestManager { //mdiatype 这个需要和服务端保持一致 private static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8"); private static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/x-www-form-urlencoded; charset=utf-8"); private static final String TAG = RequestManager.class.getSimpleName(); //请求接口根地址 private static final String BASE_URL = "http://xxxxxx/index.php?xxxxx=xxxx&xxxx"; private static volatile RequestManager mInstance; /** * get请求 */ public static final int TYPE_GET = 0; /** * post请求参数为json */ public static final int TYPE_POST_JSON = 1; /** * post请求参数为表单 */ public static final int TYPE_POST_FORM = 2; private OkHttpClient mOkHttpClient;//okHttpClient 实例 private Handler okHttpHandler;//全局处理子线程和M主线程通信 /** * 初始化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()); } /** * 获取单例引用 * * @return */ public static RequestManager getInstance(Context context) { if (!AppData.NET_AVAILABLE) { ToastUtils.showShort(context, context.getString(R.string.net_not_available)); } RequestManager inst = mInstance; if (inst == null) { synchronized (RequestManager.class) { inst = mInstance; if (inst == null) { inst = new RequestManager(context.getApplicationContext()); mInstance = inst; } } } return inst; } /** * 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同步请求 * * @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) { LogUtil.e(TAG, e.toString()); } } /** * 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 LogUtil.e(TAG, "response ----->" + response.body().string()); } } catch (Exception e) { LogUtil.e(TAG, e.toString()); } } /** * 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()) { LogUtil.e(TAG, "url: " + requestUrl + " response ----->" + response.body().string()); } } catch (Exception e) { LogUtil.e(TAG, e.toString()); } } /** * 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异步请求 * * @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++; } final 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); LogUtil.e(TAG, e.toString()); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { String string = response.body().string(); LogUtil.e(TAG, "url: " + requestUrl + " response ----->" + string); successCallBack(string, callBack); } else { failedCallBack("服务器错误", callBack); } } }); return call; } catch (Exception e) { LogUtil.e(TAG, e.toString()); } return null; } /** * 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); final 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); LogUtil.e(TAG, e.toString()); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { String string = response.body().string(); LogUtil.e(TAG, "url: " + requestUrl + " response ----->" + string); successCallBack(string, callBack); } else { failedCallBack("服务器错误", callBack); } } }); return call; } catch (Exception e) { LogUtil.e(TAG, e.toString()); } return null; } /** * 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(); final 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); LogUtil.e(TAG, e.toString()); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { String string = response.body().string(); LogUtil.e(TAG, "url: " + requestUrl + " response ----->" + string); successCallBack(string, callBack); } else { failedCallBack("服务器错误", callBack); } } }); return call; } catch (Exception e) { LogUtil.e(TAG, e.toString()); } return null; } private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/jpg"); /** * 像后台上传多张图片 type :1 用户头像上传 2 上传身份证 3 评论图片上传 */ public <T> Call sendMutilImag(String actionUrl, int type, Map<String, String> params, String pic_key, List<File> files, final ReqCallBack<T> callBack) { try { MultipartBody.Builder multipartBodyBuilder = new MultipartBody.Builder(); multipartBodyBuilder.setType(MultipartBody.FORM); //遍历map中所有参数到builder if (params != null) { for (String key : params.keySet()) { multipartBodyBuilder.addFormDataPart(key, params.get(key)); } } if (type == 1) { // //遍历paths中所有图片绝对路径到builder,并约定key如“upload”作为后台接受多张图片的key if (files != null) { for (File file : files) { multipartBodyBuilder.addFormDataPart(pic_key, file.getName(), RequestBody.create(MEDIA_TYPE_PNG, file)); } } } else if (type == 2) { //身份证上传 //遍历paths中所有图片绝对路径到builder,并约定key如“upload”作为后台接受多张图片的key if (files != null) { for (int i = 0; i < files.size(); i++) { File file = files.get(i); LogUtil.i("addFormDataPart", i + " filename : " + file.getName()); if (i == 0) { multipartBodyBuilder.addFormDataPart("card_1", file.getName(), RequestBody.create(MEDIA_TYPE_PNG, file)); } else if (i == 1) { multipartBodyBuilder.addFormDataPart("card_2", file.getName(), RequestBody.create(MEDIA_TYPE_PNG, file)); } else if (i == 2) { multipartBodyBuilder.addFormDataPart("card_3", file.getName(), RequestBody.create(MEDIA_TYPE_PNG, file)); } } } } else if (type == 3) { if (files != null) { for (int i = 0; i < files.size(); i++) { File file = files.get(i); multipartBodyBuilder.addFormDataPart("imgs" + (i + 1), file.getName(), RequestBody.create(MEDIA_TYPE_PNG, file)); LogUtil.i("filename", "filename: " + "key : " + "imgs0" + (i + 1) + "name: " + file.getName()); } } } //构建请求体 RequestBody requestBody = multipartBodyBuilder.build(); Request.Builder RequestBuilder = new Request.Builder(); final String requestUrl = String.format("%s=%s", BASE_URL, actionUrl); RequestBuilder.url(requestUrl);// 添加URL地址 RequestBuilder.post(requestBody); Request request = RequestBuilder.build(); final Call call = mOkHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { failedCallBack("访问失败", callBack); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { String string = response.body().string(); LogUtil.e(TAG, "response ----->" + string); successCallBack(string, callBack); } else { failedCallBack("服务器错误", callBack); } } }); return call; } catch (Exception e) { LogUtil.e(TAG, e.toString()); } return null; } public interface ReqCallBack<T> { /** * 响应成功 */ void onReqSuccess(T result); /** * 响应失败 */ void onReqFailed(String errorMsg); } /** * 统一为请求添加头信息 * * @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; } /** * 统一同意处理成功信息 * * @param result * @param callBack * @param <T> */ private <T> void successCallBack(final String result, final ReqCallBack<T> callBack) { okHttpHandler.post(new Runnable() { @Override public void run() { if (callBack != null) { try { TypeInfo typeInfo = ReqClassUtils.getCallbackGenericType(callBack.getClass()); callBack.onReqSuccess((T) ReqJsonUtils.parseHttpResult(typeInfo, result)); } catch (Exception e) { LogUtil.e(TAG, e.toString()); } } } }); } /** * 统一处理失败信息 * * @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); } } }); }}
public class TypeInfo { //Type泛型对象类型 private Class<?> componentType; //Type所属对象类型 private Class<?> rawType; //type private Type type; private TypeInfo(Class<?> rawType, Class<?> componentType) { this.componentType = componentType; this.rawType = rawType; } public static TypeInfo createArrayType(Class<?> componentType) { return new TypeInfo(Array.class, componentType); } public static TypeInfo createNormalType(Class<?> componentType) { return new TypeInfo(null, componentType); } public static TypeInfo createParameterizedType(Class<?> rawType, Class<?> componentType) { return new TypeInfo(rawType, componentType); } public TypeInfo(Type type) { this.type = type; if (type instanceof ParameterizedType) { //返回 Type 对象,表示声明此类型的类或接口。 this.rawType = (Class<?>) ((ParameterizedType) type).getRawType(); //getActualTypeArguments()返回表示此类型实际类型参数的 Type 对象的数组。 Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments(); this.componentType = (Class<?>) actualTypeArguments[0]; // typeReference=new TypeReference<Map<componentType,componentType>>(){}; } else if (type instanceof GenericArrayType) { //返回 Type 对象,表示声明此类型的类或接口。 this.rawType = Array.class; // 表示一种元素类型是参数化类型或者类型变量的数组类型 this.componentType = (Class<?>) ((GenericArrayType) type).getGenericComponentType(); } else { this.componentType = (Class<?>) type; } } public Type getType() { return type; } public Class<?> getComponentType() { return componentType; } public Class<?> getRawType() { return rawType; }}
public class ReqClassUtils { public static TypeInfo getCallbackGenericType(Class<?> clazz) { //获得带有泛型的父类 Type genericSuperclass = clazz.getGenericSuperclass();//Type是 Java 编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。 TypeInfo type = getGetnericType(genericSuperclass); if (type == null) { Type[] genericInterfaces = clazz.getGenericInterfaces(); if (genericInterfaces != null && genericInterfaces.length > 0) { type = getGetnericType(genericInterfaces[0]); } } return type; } private static TypeInfo getGetnericType(Type type) { if (type != null && type instanceof ParameterizedType) { //getActualTypeArguments获取参数化类型的数组,泛型可能有多个 Type[] args = ((ParameterizedType) type).getActualTypeArguments(); if (args != null && args.length > 0) { return new TypeInfo(args[0]); } } return null; }}
public class ReqJsonUtils { //基本类型映射关系Map private static final Map primitiveWrapperTypeMap = new HashMap(8); static { //添加基本类型 primitiveWrapperTypeMap.put(Boolean.class, boolean.class); primitiveWrapperTypeMap.put(Byte.class, byte.class); primitiveWrapperTypeMap.put(Character.class, char.class); primitiveWrapperTypeMap.put(Double.class, double.class); primitiveWrapperTypeMap.put(Float.class, float.class); primitiveWrapperTypeMap.put(Integer.class, int.class); primitiveWrapperTypeMap.put(Long.class, long.class); primitiveWrapperTypeMap.put(Short.class, short.class); } /** * 将JSON字符串转换成指定的用户返回值类型 * * @param type * @param jsonData * @return */ public static <T> T parseHttpResult(TypeInfo type, String jsonData) throws JSONException { // 处理Void类型的返回值 if (Void.class.isAssignableFrom(type.getComponentType())) { return null; } //获取当前type的数据类型 Class<?> rawType = type.getRawType(); //是否是Array boolean isArray = rawType != null && Array.class.isAssignableFrom(rawType); //是否是Collection boolean isCollection = rawType != null && Collection.class.isAssignableFrom(rawType); //是否是Map boolean isMap = rawType != null && Map.class.isAssignableFrom(rawType); //获取泛型类型 Class<?> componentType = type.getComponentType(); //声明结果对象 T result = null; if (isCollection) {//处理collection result = (T) JSON.parseArray(jsonData, componentType); } else if (isArray) {//处理array result = (T) JSON.parseArray(jsonData, componentType).toArray(); } else if (isMap) {//处理Map result = (T) JSONObject.parseObject(jsonData, type.getType()); } else if (componentType.isAssignableFrom(String.class)) {//处理字符串返回值 return (T) jsonData; } else { // 接口的返回类型如果是简单类型,则会封装成为一个json对象,真正的对象存储在value属性上 if (isPrimitiveOrWrapper(componentType)) { result = (T) parseObject(jsonData); } else { //处理自定义对象 result = (T) parseObject(jsonData, componentType); } } return result; } /** * 判断是否是基本数据类型 * * @param clazz * @return */ public static boolean isPrimitiveOrWrapper(Class clazz) { return (clazz.isPrimitive() || isPrimitiveWrapper(clazz)); } /** * 判断是否是基本数据类型 * * @param clazz * @return */ public static boolean isPrimitiveWrapper(Class clazz) { return primitiveWrapperTypeMap.containsKey(clazz); }}
2.图片压缩上传
使用Luban 压缩图片
compile ‘top.zibin:Luban:1.1.3’
Luban.with(this) .load(mList) .ignoreBy(100) .setTargetDir(ImageCompressUtils.getPhotoCacheDir(mContext, "imag_thum").getAbsolutePath()) .setCompressListener(new OnCompressListener() { @Override public void onStart() { } @Override public void onSuccess(File file) { fileList.add(file); try { long fileSizes = getFileSizes(file); String s = formetFileSize(fileSizes); LogUtil.i("filename", "压缩后 ----》 图片路径: " + file.getAbsolutePath() + " 图片大小:" + s); } catch (Exception e) { e.printStackTrace(); } if (fileList.size() == mList.size()) { LogUtil.i("filename", "压缩完成,上传"); RequestManager.getInstance(GoodsCommentActivity.this).sendMutilImag(NetInterface.COMMENT_MSG, 3, params, "imgs", fileList, new RequestManager.ReqCallBack<CarResult>() { @Override public void onReqSuccess(CarResult result) { if (loadingDialog.isShowing()) { loadingDialog.dismiss(); } ToastUtils.showShort(GoodsCommentActivity.this, result.msg); if (result.code == 200) { LogUtil.i("filename", "上传完成 --- "); finish(); } } @Override public void onReqFailed(String errorMsg) { } }); } } @Override public void onError(Throwable e) { } }).launch();
public static long getFileSizes(File f) throws Exception { long s = 0; if (f.exists()) { FileInputStream fis = null; fis = new FileInputStream(f); s = fis.available(); } else { f.createNewFile(); } return s; } /** * 转换文件大小 * * @param fileS * @return */ public static String formetFileSize(long fileS) { DecimalFormat df = new DecimalFormat("#.00"); String fileSizeString = ""; if (fileS < 1024) { fileSizeString = df.format((double) fileS) + "B"; } else if (fileS < 1048576) { fileSizeString = df.format((double) fileS / 1024) + "K"; } else if (fileS < 1073741824) { fileSizeString = df.format((double) fileS / 1048576) + "M"; } else { fileSizeString = df.format((double) fileS / 1073741824) + "G"; } return fileSizeString; }
上面就是我在项目中实践的结果,有好的建议指导可以留言。
阅读全文
0 0
- 项目中okhttp网络框架的封装使用
- 安卓网络请求框架okHttp的使用与封装
- OkHttpUtils - 封装了okhttp的网络框架
- OkHttpUtils - 封装了okhttp的网络框架
- OkHttpUtils - 封装了okhttp的网络框架
- OkHttpUtils - 封装了okhttp的网络框架
- okhttp网络框架的封装实用
- okhttp网络框架的使用
- OkHttp网络框架的使用
- Android中okhttp网络请求的封装
- Android:网络层的封装(使用OkHttp)
- okhttp框架的封装
- 网络请求框架(二)----改善的okHttp封装库okhttputils的使用
- Android 的OkHttp 网络请求框架的学习封装
- 完整的OKhttp请求封装的网络框架
- okHttp网络请求框架get请求的封装
- android网络访问框架OkHttp的进一步封装
- 如何封装自己的网络框架(RxJava+okHttp+Retrofit)
- 配置Jstl的Maven依赖
- linux下利用gcc编译C和C++
- 关于自定义控件的onMeasure()其中的MeasureSpec
- 第四周项目一
- Oracle中CHAR类型不足位数时,用空格自动补足位数
- 项目中okhttp网络框架的封装使用
- DFS/BFS 关于迷宫问题
- bzoj2086[Poi2010]Blocks 单调栈好题
- 浅谈MVC、MVP、MVVM架构模式的区别和联系
- EJB的优势和使用场景
- 【转】数据库基本知识:(一)导论
- HTML meta refresh 刷新与跳转(重定向)页面
- Ubuntu下图形界面SVN客户端-RabbitVCS的安装
- 进程管理