Android网络请求框架
本篇主要介绍一下Android中经常用到的网络请求框架;
客户端网络请求,就是客户端发起网络请求,经过网络框架的特殊处理,让后将请求发送的服务器,服务器根据
请求的参数,返回客户端需要的数据,经过网络框架的处理,最后返回给客户端需要的数据,具体如下图所示:
如上图所示,网络框架其实就是架设在客户端和服务器之间的通信桥梁,负责处理客户端的请求数据,并想服务器发送请求任务
然后处理服务器返回的数据,并将最终结果返回给客户端,具体代码实现如下:
网络请求类:
1 package com.jiao.yichenetframe.net; 2 3 import java.util.ArrayList; 4 import android.content.Context; 5 import android.os.AsyncTask; 6 7 import com.jiao.yichenetframe.net.RequestAsyncTask.ResponseCallBack; 8 9 /** 10 * 连接View层与网络交互的中间层 用来创建异步任务请求网络 管理所有的网络请求任务 11 * 12 */ 13 public class RequestNet { 14 public static RequestNet requestnet = null; 15 public static ArrayList<AsyncTask> arrayAsyncTask; 16 17 public static RequestNet getRequestNet() { 18 // 单例,保证整个项目中只有一个网络请求实体 19 if (requestnet == null) { 20 requestnet = new RequestNet(); 21 arrayAsyncTask = new ArrayList<AsyncTask>(); 22 } 23 return requestnet; 24 } 25 26 /** 27 * 请求网络数据 28 * */ 29 public RequestAsyncTask RequestData(Context context, String ip, 30 Object jsonObject, ResponseCallBack callBack1) { 31 RequestAsyncTask asynctask = new RequestAsyncTask(context, ip, 32 jsonObject, callBack1); 33 34 asynctask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 35 arrayAsyncTask.add(asynctask); 36 return asynctask; 37 } 38 39 }
网络任务具体执行类(真正的发起网络请求任务,处理客户端传递过来的参数,并处理服务器返回的数据)
1 package com.jiao.yichenetframe.net; 2 3 import java.io.File; 4 import java.util.ArrayList; 5 import java.util.Map; 6 import org.json.JSONException; 7 import org.json.JSONObject; 8 import android.content.Context; 9 import android.os.AsyncTask; 10 import android.text.TextUtils; 11 import com.jiao.yichenetframe.tool.ConstantTool; 12 import com.jiao.yichenetframe.tool.MsLog; 13 14 /** 15 * 主要负责网络的异步请求 16 * 17 * @author pengqm 18 * 19 */ 20 public class RequestAsyncTask extends AsyncTask<String, Integer, String> { 21 private String ip;// 接口地址 22 private Object jsonObject;// 接口参数对象 23 private ResponseCallBack callBack1;// 接口回调 24 private GetJsonRequest getJsonRequest; 25 private HttpUrlConnection_Request urlConnection_Req; 26 private ArrayList<File> arrFile = null; 27 private Context mcontext; 28 29 public RequestAsyncTask(Context context, String ip, Object jsonObject, 30 ResponseCallBack callBack1) { 31 this.ip = ip; 32 this.jsonObject = jsonObject; 33 this.callBack1 = callBack1; 34 mcontext = context; 35 getJsonRequest = new GetJsonRequest(context); 36 urlConnection_Req = new HttpUrlConnection_Request(mcontext); 37 } 38 39 public void setArrayFile(ArrayList<File> Files) { 40 arrFile = Files; 41 } 42 43 public Context getContent() { 44 return mcontext; 45 } 46 47 @Override 48 protected String doInBackground(String... arg0) { 49 String jsonarr = null; 50 MsLog.e("ip", ip); 51 try { 52 if (jsonObject == null) { 53 jsonarr = urlConnection_Req.makeHttpRequest(ip, 54 ConstantTool.post, null); 55 } else { 56 // 得到拼接的访问接口字符串 57 String jsonStr = getJsonRequest.getJsonObject(jsonObject); 58 MsLog.e("Request_jsonStr", jsonStr); 59 // 如果arrFile等于null 表示普通请求数据,否则带图片请求 60 if (!TextUtils.isEmpty(jsonStr)) { 61 if (arrFile != null) { 62 Map map = getJsonRequest.objectMap(jsonObject); 63 jsonarr = HttpUrlConnection_Request_PD.uploadSubmit(ip, 64 map, arrFile, mcontext); 65 } else { 66 jsonarr = urlConnection_Req.makeHttpRequest(ip, 67 ConstantTool.post, jsonStr); 68 } 69 } 70 } 71 } catch (Exception e) { 72 // e.printStackTrace(); 73 // publishProgress(0); 74 75 } 76 if (isCancelled()) { 77 return null; 78 } 79 MsLog.e("jsonarr----", jsonarr); 80 return jsonarr; 81 } 82 83 @Override 84 protected void onProgressUpdate(Integer... values) { 85 super.onProgressUpdate(values); 86 } 87 88 @Override 89 protected void onPostExecute(String result) { 90 super.onPostExecute(result); 91 // 接口访问完成后 将任务从任务列表中移除 92 RequestNet.getRequestNet().arrayAsyncTask.remove(this); 93 if (callBack1 == null) { 94 return; 95 } 96 if (result != null) { 97 // 根据返回值 判断是否是错误码 98 if (result.equals(ConstantTool.LOCALERRO_NETTIMEROUT)) { 99 // 网络超时 100 callBack1.onErrorResponse(ConstantTool.LOCALERRO_NETTIMEROUT); 101 } else {// 不是错误码 表示数据正常 接口访问成功 返回json字符串 102 try { 103 JSONObject jb; 104 jb = new JSONObject(result); 105 callBack1.onResponse(jb); 106 } catch (JSONException e) { 107 e.printStackTrace(); 108 // 网络异常 109 callBack1.onErrorResponse(ConstantTool.LOCALERROR_UNUSUAL); 110 } 111 } 112 } else {// 没有返回值 113 // 无网络连接 114 callBack1.onErrorResponse(ConstantTool.LOCALERRO_NONETWORK); 115 } 116 } 117 118 public interface ResponseCallBack { 119 public void onResponse(JSONObject response); 120 121 public void onErrorResponse(String error); 122 } 123 }
请求字符串处理工具类(用来处理请求参数,创建符合服务器和客户端事先约定的请求规则的请求字符串)
注:我是根据我们约定的规则来定义此类的,不同的项目或不同的公司规则不一致,可以自行修改
1 package com.jiao.yichenetframe.net; 2 3 import java.lang.reflect.Field; 4 import java.lang.reflect.Method; 5 import java.util.HashMap; 6 import java.util.Map; 7 import android.content.Context; 8 import com.google.gson.Gson; 9 10 /** 11 * 将请求接口的数据进行包装 12 * */ 13 public class GetJsonRequest { 14 public Context mcontext; 15 16 public GetJsonRequest(Context context) { 17 mcontext = context; 18 } 19 20 /** 21 * 22 * 根据对象属性名获取属性的值 23 * 24 */ 25 private Object getFieldValueByName(String fieldName, Object o) { 26 try { 27 String firstLetter = fieldName.substring(0, 1).toUpperCase(); 28 String getter = "get" + firstLetter + fieldName.substring(1); 29 Method method = o.getClass().getMethod(getter, new Class[] {}); 30 Object value = method.invoke(o, new Object[] {}); 31 return value; 32 } catch (Exception e) { 33 e.printStackTrace(); 34 return null; 35 } 36 } 37 38 /** 39 * 40 * 通过反射将实体类获取字段,进行拼装返回一个完整的字符串,用于请求服务器 41 * 42 */ 43 public String getJsonObject(Object object) { 44 Gson gson = new Gson(); 45 String j = gson.toJson(object); 46 47 //遍历实体类的各个参数值,并生成一个map集合 48 try { 49 HashMap<String, Object> map = new HashMap<String, Object>(); 50 Field[] fields = object.getClass().getDeclaredFields(); 51 for (Field field : fields) { 52 field.setAccessible(true); 53 String name = field.getName(); 54 Object value = getFieldValueByName(name, object); 55 if (value == null) { 56 value = ""; 57 } 58 map.put(name, value); 59 60 } 61 //遍历map集合,根据既定规则拼接访问接口的字符串 62 String target_string = ""; 63 for (Map.Entry<String, Object> me : map.entrySet()) { 64 target_string = target_string + me.getKey() + "=" 65 + me.getValue() + "&"; 66 } 67 //去掉最后的"&" 68 target_string = target_string.substring(0,target_string.lastIndexOf("&")); 69 return target_string; 70 } catch (Exception e) { 71 e.printStackTrace(); 72 } 73 return null; 74 } 75 76 /** 77 * 根据对象转换map,上传图片时携带的参数 78 * */ 79 public Map<String, Object> objectMap(Object object) { 80 HashMap<String, Object> map = new HashMap<String, Object>(); 81 try { 82 Field[] fields = object.getClass().getDeclaredFields(); 83 for (Field field : fields) { 84 field.setAccessible(true); 85 String name = field.getName(); 86 Object value = getFieldValueByName(name, object); 87 if (value == null) { 88 value = ""; 89 } 90 map.put(name, value); 91 } 92 return map; 93 } catch (Exception e) { 94 e.printStackTrace(); 95 } 96 return null; 97 98 } 99 100 }
网络工具类(和服务器交互,向服务器传递数据,并接收服务器返回的数据)
1 package com.jiao.yichenetframe.net; 2 3 import java.io.BufferedInputStream; 4 import java.io.BufferedOutputStream; 5 import java.io.IOException; 6 import java.io.InputStream; 7 import java.io.OutputStream; 8 import java.io.UnsupportedEncodingException; 9 import java.net.HttpURLConnection; 10 import java.net.SocketTimeoutException; 11 import java.net.URL; 12 import org.json.JSONArray; 13 import android.content.Context; 14 import com.jiao.yichenetframe.YiCheNetFrameApplication; 15 import com.jiao.yichenetframe.tool.ConstantTool; 16 import com.jiao.yichenetframe.tool.Utils; 17 18 /** 19 * 采用HttpUrlConnection请求服务类 20 * */ 21 public class HttpUrlConnection_Request { 22 InputStream inputstream = null; 23 JSONArray jObj = null; 24 String result = null; 25 public HttpUrlConnection_Request urlConnection_request = null; 26 private Context mcontext; 27 28 // constructor 29 public HttpUrlConnection_Request(Context context) { 30 mcontext = context; 31 } 32 33 // function get json from url 34 public String makeHttpRequest(String url, String method, String params) { 35 HttpURLConnection urlConnection = null; 36 // Making HTTP request 37 try { 38 String versionCode = YiCheNetFrameApplication.VERSIONCODE; 39 if (method.equals(ConstantTool.post)) { 40 urlConnection = (HttpURLConnection) new URL(url) 41 .openConnection(); 42 urlConnection.setConnectTimeout(40000); 43 urlConnection.setReadTimeout(40000); 44 urlConnection.setDoInput(true); 45 urlConnection.setDoOutput(true); 46 urlConnection.setRequestProperty("connection", "close"); 47 urlConnection.setChunkedStreamingMode(0); 48 urlConnection.setRequestMethod(method); 49 urlConnection.setRequestProperty("MallAppVersion", versionCode); 50 urlConnection.setRequestProperty("SystemType", 51 ConstantTool.SystemType); 52 urlConnection.setRequestProperty("Content-Type", 53 "application/x-www-form-urlencoded"); 54 urlConnection.setRequestProperty("AccessToken", 55 "4b5b8693-5ebb-4f34-9070-d8b3f3875ad7"); 56 urlConnection.setRequestProperty("Charsert", "UTF-8"); 57 OutputStream out = new BufferedOutputStream( 58 urlConnection.getOutputStream()); 59 if (params != null) { 60 out.write(params.getBytes("UTF-8")); 61 } 62 out.flush(); 63 out.close(); 64 int responseCode = urlConnection.getResponseCode(); 65 if (responseCode == 200) { 66 inputstream = new BufferedInputStream( 67 urlConnection.getInputStream()); 68 } else { 69 inputstream = new BufferedInputStream( 70 urlConnection.getErrorStream()); 71 } 72 } 73 result = Utils.convertStreamToString(inputstream).trim(); 74 inputstream.close(); 75 inputstream = null; 76 } catch (UnsupportedEncodingException e) { 77 e.printStackTrace(); 78 } catch (SocketTimeoutException e) { 79 result = ConstantTool.LOCALERRO_NETTIMEROUT; 80 } catch (IOException e) { 81 e.printStackTrace(); 82 } finally { 83 urlConnection.disconnect(); 84 } 85 // return JSON String 86 return result; 87 88 } 89 }
网络请求示例:
1 // 获取列表四个参数分别是:Context、url请求接口地址、object请求参数(封装对象)、请求回调 2 RequestNet.getRequestNet().RequestData(this, url, 3 object, new ResponseCallBack() { 4 @Override 5 public void onResponse(JSONObject response) { 6 7 // 网络请求成功 返回json 8 System.out.println("返回值:" + response); 9 10 } 11 12 @Override 13 public void onErrorResponse(String error) { 14 // 网络请求失败 失败原因 15 System.out.println("错误:" + error); 16 } 17 });