Android 网络请求 框架
来源:互联网 发布:淘宝热卖商品排行榜 编辑:程序博客网 时间:2024/05/22 11:41
大家好,不知不觉进行Android的开发工作已经快4年了,一直在网上观摩各位大牛的博客,令我学到了很多,在此我深表感谢,今天是小弟第一次写自己的博客,希望大家能多多指正。
废话不多说了,下面进入正题:
Http的数据交互相信大家熟悉的不能再熟悉了,每一个开发者都需要研究使用的功能,在这里,我写一下自己的一些实现方式:
首先,Http请求常用的大概有GET和POST两种请求方式,到这里,大家应该有个大概的了解,GET一般用于获取/查询资源信息,而POST一般用于更新资源信息。我们从表面上来看一下GET和POPST的区别:
1.GET请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据,参数之间以& 相连,如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0%E5%A5%BD。 POST把提交的数据则放置在是HTTP包的包体中。 2.首先是"GET"方式提交的数据最多只能是1024字节",因为GET是通过URL提交数据,那么GET可提交的数据量 就跟URL的长度有直接关系了。而实际上,URL不存在参数上限的问题,HTTP协议规范没有对URL长度进行限 制。这个限制是特定的浏览器及服务器对它的限制。IE对URL长度的限制是2083字节(2K+35)。对于其他浏览 器,如FireFox等,理论上没有长度限制,其限制取决于操作系统的支持。【注意这是限制是整个URL长度, 而不仅仅是你的参数值数据长度。】 然后是POST是没有大小限制的,HTTP协议规范也没有进行大小限制,说“POST数据量存在80K/100K的大小限 制”是不准确的,POST数据是没有限制的,起限制作用的是服务器的处理程序的处理能力。
HTTP协议(HyperText Transfer Protocol,超文本传输协议)的实现原理在这里就不在做多赘述了,下面直接进入代码,由于本代码在okhttp的基础上完成整理,代码中注释也写了很多,这里就直接上代码了:
首先我们写一个类HttpAddress,主要存一些接口地址等常量以及各位自定义的一些数据常量等,例:
package com.hs.http;import java.util.HashMap;import java.util.Map;/** * 存放所有接口地址 * Created by ZM on 2016/7/13 0022. */class HttpAddress { /** * post请求类型传入Map */ public static final String HttpTypeMap = "Map"; /** * post请求类型传入Json */ public static final String HttpTypeJson = "JSON"; public static final String CodeThird="error_code"; public static final String MsgThird="reason"; public static final String DataThird="data"; public static final String CodeLocal="code"; public static final String MsgLocal="msg"; public static final String DataLocal="data"; /** * H5域名 */ public static String URL_H5 = "https://www.xiaomoc.com/indiana-app/"; /** * 推广H5 */ public static String URL_H5_PROMPT = URL_H5 + "html/microSite.html"; /** * 接口地址(第三方接口服务器地址) */ public static String URL_HTTP_THRID = "http://v.juhe.cn/"; /** * 接口地址(我的App服务器地址) */ public static String URL_HTTP = "https://www.xiaomoc.com/indiana-app/"; /** * 图片服务器地址 */ public static String URL_IMAGE = "http://120.77.13.93/"; /** * 设置USERID */ public static int UserID; public static int getUserID() { return UserID; } public static void setUserID(int userID) { UserID = userID; } protected static final Map<Integer, String> address = new HashMap(); /*分享Image图片URL*/ public static final String SHAREIMAGE = "http://www.xiaomoc.top/0986e377ef7e996aa077234080630fd1"; private static final String TAG = "HttpAddress"; public static final int NEWS=0; static { address.put(NEWS, "app/carnews/list"); }}
然后,我们来写一个回调的监听接口类:HttpCallbackListener
package com.hs.http;/** * Created by ${ZM} on 2016/7/13 0013. */public interface HttpCallbackListener<T> { /** * 没有网络时返回 */ void noNetwork(int code,String msg); /** * 未知错误返回 * @param msg 错误信息 */ void unknownError(int code,String msg); /** * 失败时返回 * * @param code 错误码 * @param msg 错误信息 */ void failure(int code, String msg); /** * 成功时返回 * @param t */ void success(int id,T t);}
第三步,建立我们的请求方法,这里的例子根据我自己项目中用的,首先创建请求体,然后通过一些接口回调完成数据的传输,并在成功时缓存了获取到的数据,方便在下一次因为某些原因获取失败时,直接返回上一次缓存的数据,然后获取里面包含了Get,Post(这里因为项目需要,写了两种请求体的生成方式),可能有些地方对于大家来说是多余的,以下就不说了,直接上全部代码了,大家仅仅做个参考:
HttpRequest:
package com.hs.http;import android.app.Activity;import android.content.Context;import android.util.Log;import com.squareup.okhttp.Call;import com.squareup.okhttp.Callback;import com.squareup.okhttp.FormEncodingBuilder;import com.squareup.okhttp.MediaType;import com.squareup.okhttp.MultipartBuilder;import com.squareup.okhttp.OkHttpClient;import com.squareup.okhttp.Request;import com.squareup.okhttp.RequestBody;import com.squareup.okhttp.Response;import java.io.File;import java.io.IOException;import java.util.HashMap;import java.util.List;import java.util.UUID;import java.util.concurrent.TimeUnit;import cn.ljguo.security.AESAndroid;import cn.ljguo.security.MD5;import demo.hs.util.NetWorkUtil;/** * Created by ZM on 2016/7/13 0013. */abstract class HttpRequest extends HttpAddress { private final static String TAG = "HTTP";// md5加密(本App中没用到)// if (BuildConfig.IS_HTTP_ENCRYPTED) {// json = MobileKit.encryptMobileText(json.toString());// }// md5解密(本App中没用到)// if (BuildConfig.IS_HTTP_ENCRYPTED) {// content = MobileKit.decryptMobileText(content);// Log.e(TAG, "获取服务器加密后的数据=[" + content + "]");// } else {// Log.e(TAG, "获取到数据=[" + content + "]");// } /*** * POST方式传参请求 * * @param id 接口Id * @param isThrid true--第三方接口服务器 false--自己App后台提供的服务器 * @param httpType HttpTypeMap--传入map类型 HttpTypeJson--传入json类型 * @param result 返回的bean集合 * @param context 上下文 * @param builder httpType为HttpTypeMap时,传入Builder对象,否则传NUll * @param json httpType为HttpTypeJson时,传入String对象,否则传NUll * @param callback 回调接口 */ protected void requestPost(final int id, final boolean isThrid, String httpType, final IHttpResult result, final Context context, FormEncodingBuilder builder, final String json, final HttpCallbackListener callback) { String url = null; if (isThrid) { url = URL_HTTP_THRID + HttpAddress.address.get(id); } else { url = URL_HTTP + HttpAddress.address.get(id); } if (!NetWorkUtil.isNetworkAvailable(context)) { callback.noNetwork(id, "请检查您的网络连接"); getCatch(isThrid, id, result, context, callback); return; } OkHttpClient client = new OkHttpClient(); client.setConnectTimeout(10, TimeUnit.SECONDS); client.setWriteTimeout(10, TimeUnit.SECONDS); client.setReadTimeout(30, TimeUnit.SECONDS); Request request = null; switch (httpType) { case HttpTypeMap: Log.e(TAG, "请求的接口=" + url + "传入的参数=" + builder.toString()); request = new Request.Builder().url(url).post(builder.build()).build(); break; case HttpTypeJson: Log.e(TAG, "请求的接口=" + url + "传入的参数=" + json.toString()); final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); request = new Request.Builder().url(url).post(RequestBody.create(JSON, json.toString())).build(); break; } CallHttp(client, request, context, id, isThrid, true, result, callback); } /*** * Get方式请求数据 * * @param id 接口Id * @param isThrid true--第三方接口服务器 false--自己App后台提供的服务器 * @param result 返回的bean集合 * @param context 上下文 * @param json 传入String对象 * @param callback 回调接口 */ protected void requestGet(final int id, final boolean isThrid, final IHttpResult result, final Context context, final String json, final HttpCallbackListener callback) { String url = null; if (isThrid) { url = URL_HTTP_THRID + HttpAddress.address.get(id) + json; } else { url = URL_HTTP + HttpAddress.address.get(id) + json; } if (!NetWorkUtil.isNetworkAvailable(context)) { callback.noNetwork(id, "请检查您的网络连接"); getCatch(isThrid, id, result, context, callback); return; } Log.e(TAG, "请求的接口=" + url); OkHttpClient client = new OkHttpClient(); client.setConnectTimeout(10, TimeUnit.SECONDS); client.setWriteTimeout(10, TimeUnit.SECONDS); client.setReadTimeout(30, TimeUnit.SECONDS); final Request request = new Request.Builder().url(url).get().build(); CallHttp(client, request, context, id, isThrid, true, result, callback); } /*** * 上传Image图片到服务器 * @param id 接口Id * @param result 返回的bean集合 * @param context 上下文 * @param map 传入的Map参数对象 * @param files 传入的文件对象 * @param callback 回调接口 */ protected void requestPostImage(final int id, final IHttpResult result, final Context context, final HashMap<String, String> map, List<File> files, final HttpCallbackListener callback) { final String url = URL_HTTP + HttpAddress.address.get(id); if (!NetWorkUtil.isNetworkAvailable(context)) { callback.noNetwork(id, "请检查您的网络连接"); return; } Log.d(TAG, "请求的接口=" + url); final MediaType MEDIA_TYPE_PNG = MediaType.parse("multipart/form-data"); //创建OkHttpClient实例 final OkHttpClient client = new OkHttpClient(); MultipartBuilder builder = new MultipartBuilder().type(MultipartBuilder.FORM); //遍历map中所有参数到builder if (map != null && map.size() != 0) { for (String key : map.keySet()) { builder.addFormDataPart(key, map.get(key)); } } if (files != null && files.size() != 0) { //遍历paths中所有图片绝对路径到builder,并约定key如“upload”作为后台接受多张图片的key for (File file : files) { builder.addFormDataPart(UUID.randomUUID().toString(), file.getName(), RequestBody.create(MEDIA_TYPE_PNG, file)); } } //构建请求体 RequestBody requestBody = builder.build(); //构建请求 Request request = new Request.Builder() .url(url)//地址 .post(requestBody)//添加请求体 .build(); CallHttp(client, request, context, id, false, false, result, callback); } /*** * 构建请求以及获取返回数据 * * @param client * @param request * @param context * @param id * @param isThrid * @param isCatch * @param result * @param callback */ public void CallHttp(OkHttpClient client, Request request, final Context context, final int id, final boolean isThrid, final boolean isCatch, final IHttpResult result, final HttpCallbackListener callback) { Call call = client.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Request request, final IOException e) { Log.e(TAG, "request=" + request + " IOException=" + e); if (isCatch) { getCatch(isThrid, id, result, context, callback); } unknowError(context, id, e.getMessage(), callback); } @Override public void onResponse(final Response response) throws IOException { if (response.code() == 200) { String content = response.body().string(); final String _content = content; Log.d(TAG, "获取到数据=[" + content + "]"); if (isCatch) { setCatch(context, content, id); } getResultSuccess(context, isThrid, id, result, _content, callback); } else { if (isCatch) { Log.e(TAG, "请求服务器出错取缓存=[" + response.body().string() + "]"); getCatch(isThrid, id, result, context, callback); } else { Log.e(TAG, "请求服务器出错=[" + response.body().string() + "]"); } unknowError(context, id, response.message(), callback); } } }); } /*** * 写入缓存 * * @param context * @param content * @param id */ protected void setCatch(Context context, String content, int id) { try { /*需要缓存数据时,加密后保存在本地缓存*/ if (BuildConfig.IS_HTTP_CACHE) { ACache cache = ACache.get(context); content = AESAndroid.encrypt(content, BuildConfig.HTTP_CACHE_PASSWORD); Log.e(TAG, "写入缓存的内容=" + content); cache.put(MD5.MD5Encode(HttpAddress.address.get(id)), content); } } catch (Exception e) { Log.e(TAG, "写入缓存失败"); } } /*** * 获取缓存数据 * * @param isThrid * @param id * @param result * @param context * @param callback */ protected void getCatch(boolean isThrid, int id, IHttpResult result, Context context, HttpCallbackListener callback) { if (isThrid) { getCache(id, result, context, HttpAddress.address.get(id), CodeThird, MsgThird, DataThird, callback); } else { getCache(id, result, context, HttpAddress.address.get(id), CodeLocal, MsgLocal, DataLocal, callback); } } /*** * 获取数据成功 * * @param context * @param isThrid * @param id * @param result * @param _content * @param callback */ protected void getResultSuccess(final Context context, final boolean isThrid, final int id, final IHttpResult result, final String _content, final HttpCallbackListener callback) { if (context instanceof Activity) { ((Activity) context).runOnUiThread(new Runnable() { @Override public void run() { if (isThrid) { result(id, result, context, _content, CodeThird, MsgThird, DataThird, callback); } else { result(id, result, context, _content, CodeLocal, MsgLocal, DataLocal, callback); } } }); } else { if (isThrid) { result(id, result, context, _content, CodeThird, MsgThird, DataThird, callback); } else { result(id, result, context, _content, CodeLocal, MsgLocal, DataLocal, callback); } } } /*** * 当错误时返回错误信息 * * @param context * @param id * @param msg * @param callback */ protected void unknowError(Context context, final int id, final String msg, final HttpCallbackListener callback) { if (context instanceof Activity) { ((Activity) context).runOnUiThread(new Runnable() { @Override public void run() { callback.unknownError(id, msg); } }); } else { callback.unknownError(id, msg); } } /*** * Http请求失败时获取之前成功时的缓存信息(通过解密之前保存的缓存数据获取) * * @param id * @param result * @param context * @param key * @param c * @param m * @param d * @param callback */ private void getCache(int id, IHttpResult result, Context context, String key, String c, String m, String d, HttpCallbackListener callback) { try { if (BuildConfig.IS_HTTP_CACHE) { ACache cache = ACache.get(context); String content = cache.getAsString(MD5.MD5Encode(key)); if (content != null && !content.isEmpty()) { content = AESAndroid.decrypt(content, BuildConfig.HTTP_CACHE_PASSWORD); Log.e(TAG, "读取缓存数据=" + content); result(id, result, context, content, c, m, d, callback); } } } catch (Exception e) { Log.e(TAG, e.getMessage()); } } protected abstract void result(Integer id, IHttpResult result, Context context, String json, String code, String msg, String data, HttpCallbackListener callback);}
HttpResult:
package com.hs.http;import android.content.Context;import android.text.TextUtils;import android.util.Log;import com.google.gson.JsonDeserializationContext;import com.google.gson.JsonDeserializer;import com.google.gson.JsonElement;import com.google.gson.JsonParseException;import com.google.gson.JsonPrimitive;import com.google.gson.JsonSerializationContext;import com.google.gson.JsonSerializer;import org.json.JSONException;import org.json.JSONObject;import java.lang.reflect.Proxy;import java.lang.reflect.Type;/** * Created by ZM on 2016/7/13 0013. */public class HttpResult extends HttpRequest { @Override protected void result(Integer id, IHttpResult result, Context context, String json,String c,String m,String d, HttpCallbackListener callback) { try { JSONObject jsonObject = new JSONObject(json); int code = jsonObject.getInt(c); if (code == 200) { HttpResultHandler handler = new HttpResultHandler(result); IHttpResult proxy = (IHttpResult) Proxy.newProxyInstance(result.getClass().getClassLoader(), result.getClass().getInterfaces(), handler); proxy.result(context, id, jsonObject, callback); } else { String msg=""; msg = jsonObject.getString(m); if(TextUtils.isEmpty(msg)){ msg=jsonObject.getString(d); } callback.failure(id, msg); } } catch (JSONException e) { callback.unknownError(id,e.getMessage()); } } protected class StringConverter implements JsonSerializer<String>, JsonDeserializer<String> { public JsonElement serialize(String src, Type typeOfSrc, JsonSerializationContext context) { if (src == null) { return new JsonPrimitive(""); } else { return new JsonPrimitive(src.toString()); } } public String deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { return json.getAsJsonPrimitive().getAsString(); } }}
BaseHttpResult:
package com.hs.http;import android.content.Context;import android.util.Log;import com.google.gson.Gson;import com.google.gson.reflect.TypeToken;import org.json.JSONObject;import java.util.List;/** * Created by ZM on 2016/7/13 0013. */public class BaseHttpResult extends HttpResult{ private final static String TAG="BaseHttpResult"; protected class ResultList<T> implements IHttpResult<T> { private String mTag; private Class mClass; public ResultList(String tag,Class c){ mTag=tag; this.mClass=c; } @Override public void result(Context context, Integer id, JSONObject jsonObject, HttpCallbackListener callback) { try { Gson gson = new Gson(); String json=""; if(mTag!=null&&!mTag.equals("")){ json=jsonObject.get(mTag).toString(); }else{ json=jsonObject.toString(); } List<T> playDaysOfMonthList = gson.fromJson(json,new TypeToken<List<T>>(){}.getType()); callback.success(id, playDaysOfMonthList); } catch (Exception e) { callback.unknownError(id,e.getMessage()); } } } protected class ResultBean<T> implements IHttpResult{ private Class c; private String mTag; public ResultBean(Class c){ this.c=c; } public ResultBean(Class c,String tag){ this.c=c; this.mTag=tag; } @Override public void result(Context context, Integer id, JSONObject jsonObject, HttpCallbackListener callback) { try { Log.d(TAG,"t="+c); String json=""; if(mTag!=null&&!mTag.equals("")){ json=jsonObject.get(mTag).toString(); }else{ json=jsonObject.toString(); } T t = (T) new Gson().fromJson(json,c); callback.success(id, t); } catch (Exception e) { callback.unknownError(id,e.getMessage()); } } } protected class ResultMap implements IHttpResult{ @Override public void result(Context context, Integer id, JSONObject jsonObject, HttpCallbackListener callback) { try { callback.success(id, JsonToMap.toMap(jsonObject.toString())); } catch (Exception e) { callback.unknownError(id,e.getMessage()); } } } protected class ResultSuccess implements IHttpResult{ @Override public void result(Context context, Integer id, JSONObject jsonObject, HttpCallbackListener callback) { try { callback.success(id,jsonObject); } catch (Exception e) { callback.unknownError(id,e.getMessage()); } } }}
HsHttpResult(这里写自己需要返回的内容):
package com.hs.http;import android.content.Context;import com.google.gson.Gson;import com.google.gson.reflect.TypeToken;import com.hs.data.TestBean;import org.json.JSONObject;import java.util.List;/** * Created by ZM on 2016/7/13 0013. */public class HsHttpResult extends BaseHttpResult { /*** * 获取新闻列表json返回 */ protected class getNewsList implements IHttpResult { @Override public void result(Context context, Integer id, JSONObject jsonObject, HttpCallbackListener callback) { try { List<TestBean> info=new Gson().fromJson(jsonObject.getString("data"),new TypeToken<List<TestBean>>() { }.getType()); callback.success(id, info); } catch (Exception e) { callback.unknownError(id,e.getMessage()); } } }}
HttpResultHandler:
package com.hs.http;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;/** * Created by ZM on 2016/7/13 0013. */public class HttpResultHandler implements InvocationHandler { private Object mObject; protected HttpResultHandler(Object object) { super(); this.mObject = object; } public Object invoke(Object proxy, Method method, Object... args) throws Throwable { Object result = null; result = method.invoke(mObject, args); return result; }}
IHttpResult:
package com.hs.http;import android.content.Context;import org.json.JSONObject;/** * Created by ZM on 2016/7/13 0013. */public interface IHttpResult<T> { void result(Context context, Integer id, JSONObject jsonObject, HttpCallbackListener callback);}
JsonToMap:
package com.hs.http;import com.google.gson.Gson;import com.google.gson.reflect.TypeToken;import java.util.List;import java.util.Map;/** * Created by ZM on 2016/7/13 0013. */public class JsonToMap { /** * 根据json字符串返回Map对象 * * @param json * @return */ protected static Map<String, Object> toMap(String json) { return new Gson().fromJson(json, new TypeToken<Map<String, Object>>() { }.getType()); } protected static List<Map<String,Object>> toList(String json){ return new Gson().fromJson(json, new TypeToken<List<Map<String, Object>>>() { }.getType()); }}
最后 Http:
package com.hs.http;import android.content.Context;/** * 存放所有接口请求 * Created by ZM on 2016/7/13 0013. */public class Http extends HsHttpResult { /*** * 获取新闻列表 * * @param context * @param callback */ public void getNewsList(Context context, int currentPage, int numPerPage, HttpCallbackListener callback) { requestGet(NEWS,false,new getNewsList(),context,"?currentPage=" + currentPage + "&numPerPage="+numPerPage,callback); }// /***// * 上传头像// *// * @param context// * @param files// * @param callback// */// public void uploadHeader(Context context, String userid, List<File> files, HttpCallbackListener callback) {// HashMap<String,String> map=new HashMap<>();// map.put("userId", userid);// request(UPLOADHEADER,new loginResult(),context,map,files,callback);// }}
使用方式示例 TestActivity:
package com.hs.qianshubao.wealth.base;import android.app.Activity;import android.os.Bundle;import com.hs.data.TestBean;import com.hs.http.Http;import com.hs.http.HttpCallbackListener;import com.hs.qianshubao.wealth.R;import java.util.List;/** * Created by ZM on 2017/4/18 0018. */public class TestActivity extends Activity implements HttpCallbackListener { public static String TAG="TestActivity"; Http http; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); http=new Http(); http.getNewsList(this,1,10,this); } @Override public void noNetwork(int code, String msg) { /*这里处理没网的情况 code-请求的接口ID ,例:NEWS ,msg----说明语句*/ } @Override public void unknownError(int code, String msg) { /*这里处理出现位置错误的情况 code-请求的接口ID ,例:NEWS ,msg----错误提示*/ } @Override public void failure(int code, String msg) { /*这里处理出现一些服务器错误的情况 code-请求的接口ID ,例:NEWS ,msg----错误提示*/ } @Override public void success(int id, Object o) { /*这里处理请求成功后的情况 id-请求的接口ID ,例:NEWS ,o----在HsHttpResult获取的返回内容 */ List<TestBean> mList= (List<TestBean>) o; Log.e(TAG,"====="+mList.toString()); }}
今天就到这里了,欢迎各位大牛批评指正,感谢!
下载链接:http://download.csdn.net/detail/zhang6511828/9818075
- Android网络请求框架
- Android 网络请求 框架
- Android简易网络请求框架
- Android网络请求框架 Volley
- Android网络请求框架--AsyncHttpClient
- 轻量级Android网络请求框架
- Android网络请求框架Volley
- Android主流网络请求框架
- android中的网络请求框架
- Android主流网络请求框架
- android网络请求框架汇总
- Android网络请求框架Volley
- Android Volley网络请求框架
- Android网络请求框架----okHttp3
- Android网络请求框架-----Volley
- Android主流网络请求框架
- Android 网络请求框架汇总
- Android常用框架----网络请求系列框架
- 雪城大学信息安全讲义 3.1 Set-UID 机制如何工作
- 腾讯课堂IMWeb Vue.js 笔记
- Android中AsyncTask的介绍,示例和原理分析
- react-router 学习笔记
- poj3348 Cows【凸包面积】
- Android 网络请求 框架
- 1023. Have Fun with Numbers (20)
- UVA 7340 Sum of MSLCM
- centos7环境下搭建storm集群
- 浏览器兼容问题项目总结(五)table中td和li高度问题
- (原创)分享自己写的几个工具类(四)BigDecimal精确计算
- MTK lk源码解析7( lk 阶段aboot.c 解析)
- js中如何查看原型
- 手机端切图转静态页工具文档