本篇主要介绍一下Android中经常用到的网络请求框架;
客户端网络请求,就是客户端发起网络请求,经过网络框架的特殊处理,让后将请求发送的服务器,服务器根据
请求的参数,返回客户端需要的数据,经过网络框架的处理,最后返回给客户端需要的数据,具体如下图所示:
如上图所示,网络框架其实就是架设在客户端和服务器之间的通信桥梁,负责处理客户端的请求数据,并想服务器发送请求任务
然后处理服务器返回的数据,并将最终结果返回给客户端,具体代码实现如下:
网络请求类:
package com.jiao.yichenetframe.net; import java.util.ArrayList;
import android.content.Context;
import android.os.AsyncTask; import com.jiao.yichenetframe.net.RequestAsyncTask.ResponseCallBack; /**
* 连接View层与网络交互的中间层 用来创建异步任务请求网络 管理所有的网络请求任务
*
*/
public class RequestNet {
public static RequestNet requestnet = null;
public static ArrayList<AsyncTask> arrayAsyncTask; public static RequestNet getRequestNet() {
// 单例,保证整个项目中只有一个网络请求实体
if (requestnet == null) {
requestnet = new RequestNet();
arrayAsyncTask = new ArrayList<AsyncTask>();
}
return requestnet;
} /**
* 请求网络数据
* */
public RequestAsyncTask RequestData(Context context, String ip,
Object jsonObject, ResponseCallBack callBack1) {
RequestAsyncTask asynctask = new RequestAsyncTask(context, ip,
jsonObject, callBack1); asynctask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
arrayAsyncTask.add(asynctask);
return asynctask;
} }
网络任务具体执行类(真正的发起网络请求任务,处理客户端传递过来的参数,并处理服务器返回的数据)
package com.jiao.yichenetframe.net; import java.io.File;
import java.util.ArrayList;
import java.util.Map;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Context;
import android.os.AsyncTask;
import android.text.TextUtils;
import com.jiao.yichenetframe.tool.ConstantTool;
import com.jiao.yichenetframe.tool.MsLog; /**
* 主要负责网络的异步请求
*
* @author pengqm
*
*/
public class RequestAsyncTask extends AsyncTask<String, Integer, String> {
private String ip;// 接口地址
private Object jsonObject;// 接口参数对象
private ResponseCallBack callBack1;// 接口回调
private GetJsonRequest getJsonRequest;
private HttpUrlConnection_Request urlConnection_Req;
private ArrayList<File> arrFile = null;
private Context mcontext; public RequestAsyncTask(Context context, String ip, Object jsonObject,
ResponseCallBack callBack1) {
this.ip = ip;
this.jsonObject = jsonObject;
this.callBack1 = callBack1;
mcontext = context;
getJsonRequest = new GetJsonRequest(context);
urlConnection_Req = new HttpUrlConnection_Request(mcontext);
} public void setArrayFile(ArrayList<File> Files) {
arrFile = Files;
} public Context getContent() {
return mcontext;
} @Override
protected String doInBackground(String... arg0) {
String jsonarr = null;
MsLog.e("ip", ip);
try {
if (jsonObject == null) {
jsonarr = urlConnection_Req.makeHttpRequest(ip,
ConstantTool.post, null);
} else {
// 得到拼接的访问接口字符串
String jsonStr = getJsonRequest.getJsonObject(jsonObject);
MsLog.e("Request_jsonStr", jsonStr);
// 如果arrFile等于null 表示普通请求数据,否则带图片请求
if (!TextUtils.isEmpty(jsonStr)) {
if (arrFile != null) {
Map map = getJsonRequest.objectMap(jsonObject);
jsonarr = HttpUrlConnection_Request_PD.uploadSubmit(ip,
map, arrFile, mcontext);
} else {
jsonarr = urlConnection_Req.makeHttpRequest(ip,
ConstantTool.post, jsonStr);
}
}
}
} catch (Exception e) {
// e.printStackTrace();
// publishProgress(0); }
if (isCancelled()) {
return null;
}
MsLog.e("jsonarr----", jsonarr);
return jsonarr;
} @Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
} @Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// 接口访问完成后 将任务从任务列表中移除
RequestNet.getRequestNet().arrayAsyncTask.remove(this);
if (callBack1 == null) {
return;
}
if (result != null) {
// 根据返回值 判断是否是错误码
if (result.equals(ConstantTool.LOCALERRO_NETTIMEROUT)) {
// 网络超时
callBack1.onErrorResponse(ConstantTool.LOCALERRO_NETTIMEROUT);
} else {// 不是错误码 表示数据正常 接口访问成功 返回json字符串
try {
JSONObject jb;
jb = new JSONObject(result);
callBack1.onResponse(jb);
} catch (JSONException e) {
e.printStackTrace();
// 网络异常
callBack1.onErrorResponse(ConstantTool.LOCALERROR_UNUSUAL);
}
}
} else {// 没有返回值
// 无网络连接
callBack1.onErrorResponse(ConstantTool.LOCALERRO_NONETWORK);
}
} public interface ResponseCallBack {
public void onResponse(JSONObject response); public void onErrorResponse(String error);
}
}
请求字符串处理工具类(用来处理请求参数,创建符合服务器和客户端事先约定的请求规则的请求字符串)
注:我是根据我们约定的规则来定义此类的,不同的项目或不同的公司规则不一致,可以自行修改
package com.jiao.yichenetframe.net; import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import android.content.Context;
import com.google.gson.Gson; /**
* 将请求接口的数据进行包装
* */
public class GetJsonRequest {
public Context mcontext; public GetJsonRequest(Context context) {
mcontext = context;
} /**
*
* 根据对象属性名获取属性的值
*
*/
private Object getFieldValueByName(String fieldName, Object o) {
try {
String firstLetter = fieldName.substring(0, 1).toUpperCase();
String getter = "get" + firstLetter + fieldName.substring(1);
Method method = o.getClass().getMethod(getter, new Class[] {});
Object value = method.invoke(o, new Object[] {});
return value;
} catch (Exception e) {
e.printStackTrace();
return null;
}
} /**
*
* 通过反射将实体类获取字段,进行拼装返回一个完整的字符串,用于请求服务器
*
*/
public String getJsonObject(Object object) {
Gson gson = new Gson();
String j = gson.toJson(object); //遍历实体类的各个参数值,并生成一个map集合
try {
HashMap<String, Object> map = new HashMap<String, Object>();
Field[] fields = object.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
String name = field.getName();
Object value = getFieldValueByName(name, object);
if (value == null) {
value = "";
}
map.put(name, value); }
//遍历map集合,根据既定规则拼接访问接口的字符串
String target_string = "";
for (Map.Entry<String, Object> me : map.entrySet()) {
target_string = target_string + me.getKey() + "="
+ me.getValue() + "&";
}
//去掉最后的"&"
target_string = target_string.substring(0,target_string.lastIndexOf("&"));
return target_string;
} catch (Exception e) {
e.printStackTrace();
}
return null;
} /**
* 根据对象转换map,上传图片时携带的参数
* */
public Map<String, Object> objectMap(Object object) {
HashMap<String, Object> map = new HashMap<String, Object>();
try {
Field[] fields = object.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
String name = field.getName();
Object value = getFieldValueByName(name, object);
if (value == null) {
value = "";
}
map.put(name, value);
}
return map;
} catch (Exception e) {
e.printStackTrace();
}
return null; } }
网络工具类(和服务器交互,向服务器传递数据,并接收服务器返回的数据)
package com.jiao.yichenetframe.net; import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import org.json.JSONArray;
import android.content.Context;
import com.jiao.yichenetframe.YiCheNetFrameApplication;
import com.jiao.yichenetframe.tool.ConstantTool;
import com.jiao.yichenetframe.tool.Utils; /**
* 采用HttpUrlConnection请求服务类
* */
public class HttpUrlConnection_Request {
InputStream inputstream = null;
JSONArray jObj = null;
String result = null;
public HttpUrlConnection_Request urlConnection_request = null;
private Context mcontext; // constructor
public HttpUrlConnection_Request(Context context) {
mcontext = context;
} // function get json from url
public String makeHttpRequest(String url, String method, String params) {
HttpURLConnection urlConnection = null;
// Making HTTP request
try {
String versionCode = YiCheNetFrameApplication.VERSIONCODE;
if (method.equals(ConstantTool.post)) {
urlConnection = (HttpURLConnection) new URL(url)
.openConnection();
urlConnection.setConnectTimeout(40000);
urlConnection.setReadTimeout(40000);
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty("connection", "close");
urlConnection.setChunkedStreamingMode(0);
urlConnection.setRequestMethod(method);
urlConnection.setRequestProperty("MallAppVersion", versionCode);
urlConnection.setRequestProperty("SystemType",
ConstantTool.SystemType);
urlConnection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
urlConnection.setRequestProperty("AccessToken",
"4b5b8693-5ebb-4f34-9070-d8b3f3875ad7");
urlConnection.setRequestProperty("Charsert", "UTF-8");
OutputStream out = new BufferedOutputStream(
urlConnection.getOutputStream());
if (params != null) {
out.write(params.getBytes("UTF-8"));
}
out.flush();
out.close();
int responseCode = urlConnection.getResponseCode();
if (responseCode == 200) {
inputstream = new BufferedInputStream(
urlConnection.getInputStream());
} else {
inputstream = new BufferedInputStream(
urlConnection.getErrorStream());
}
}
result = Utils.convertStreamToString(inputstream).trim();
inputstream.close();
inputstream = null;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (SocketTimeoutException e) {
result = ConstantTool.LOCALERRO_NETTIMEROUT;
} catch (IOException e) {
e.printStackTrace();
} finally {
urlConnection.disconnect();
}
// return JSON String
return result; }
}
网络请求示例:
// 获取列表四个参数分别是:Context、url请求接口地址、object请求参数(封装对象)、请求回调
RequestNet.getRequestNet().RequestData(this, url,
object, new ResponseCallBack() {
@Override
public void onResponse(JSONObject response) { // 网络请求成功 返回json
System.out.println("返回值:" + response); } @Override
public void onErrorResponse(String error) {
// 网络请求失败 失败原因
System.out.println("错误:" + error);
}
});