在网上看到过很多在android上使用的开源的http通信库,google官方也出了个volley,空闲时间也分析过源代码,代码结构很优秀,在我做的几个应用中都使用到volley做为应用的http通信库,不重复造轮子吗!出于个人习惯和代码优雅追求的目的,这个轮子还是得再造一个,并且是量身定造,因为在以后开发应用中,http通讯库是毕不可少的,所以思前想后,还是决定写出一个轻量级的http通信库。
目前构思是想把它设计成同步请求和异步请求结合回调方法的方式,这样在使用同步请求时可以结合android中的AsyncTask一起使用,异步请求时结合回调方法来完成http请求和响应。还是看代码吧,对着代码更好理解,下面代码就是异步请求的调用,从方法名就可以看出来,在调用时要分别传入请求的url、RequestCallback回调类,其中RequestCallback类中request()方法是需要指定的请求方式,requestParams()方法是要传入的请求参数,onPostExecute()方法就是请求后所得到的结果。
post方法需要指定请求器和参数,如果不需要参数可以省略参数:SmartHttpRequest类中asyncPost方法所对应的源码如下,这里使用的java的类型推断,这样也算对得起我给他取的类名吧!RequestCallback<T>对应着请求方式,比如上面代码中return new JSONRequest();如果返回的结果是String类型,那么就是相应的改成RequestCallback<String>和return new StringRequest();还是看代码吧,更能说清楚问题。SmartHttpRequest httpRequest = new SmartHttpRequest(this); httpRequest.asyncPost("http://www.teleye.cn", new RequestCallback<JSONObject>() { @Override public Request<JSONObject> request() { return new JSONRequest(); } @Override public List<NameValuePair> requestParams() { List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); return nameValuePairs; } @Override public void onPostExecute(JSONObject result) { boolean success = result.optBoolean("success"); if(success){ try { JSONArray data = result.getJSONArray("data"); } catch (JSONException e) { e.printStackTrace(); } } } });
public <T> T asyncPost(final String url,final RequestCallback<T> callback){ addHandlerToContext(); callback.onPreExecute(); executor.execute(new Runnable() { @Override public void run() { T resultValue = null; try { List<NameValuePair> nameValuePairList = callback.requestParams(); NameValuePair[] nameValuePairs = null; if(nameValuePairList != null && nameValuePairList.size() > 0){ nameValuePairs = new NameValuePair[nameValuePairList.size()]; nameValuePairList.toArray(nameValuePairs); } resultValue = post(url,callback.request(), nameValuePairs); } catch (ServerError serverError) { serverError.printStackTrace(); } catch (ParseError parseError) { parseError.printStackTrace(); } catch (NetworkError networkError) { networkError.printStackTrace(); } finally { final T finalResultValue = resultValue; mHandler.post(new Runnable() { @Override public void run() { callback.onPostExecute(finalResultValue); } }); } } }); return null; }
换成String结果的请求调用代码:SmartHttpRequest httpRequest = new SmartHttpRequest(this); httpRequest.asyncPost("http://www.teleye.cn", new RequestCallback<String>() { @Override public Request<String> request() { return new StringRequest(); } @Override public List<NameValuePair> requestParams() { List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); return nameValuePairs; } @Override public void onPostExecute(String result) { } });
public <T> T post(String url,Request<T> request, NameValuePair... nameValuePairs) throws ServerError, ParseError, NetworkError {
try {
HttpResponse httpResponse = postRequest(url, nameValuePairs);
long requestStart = SystemClock.elapsedRealtime();
byte[] responseContents = null;
StatusLine statusLine = httpResponse.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (httpResponse.getEntity() != null) {
responseContents = entityToBytes(httpResponse.getEntity());
}
// if the request is slow, log it.
long requestLifetime = SystemClock.elapsedRealtime() - requestStart;
if (statusCode < 200 || statusCode > 299) {
throw new IOException();
}
return request.parserResponse(responseContents);
} catch (IOException e) {
throw new NetworkError(e);
}
}
同步请求的方式在使用时需要结合线程或任务来使用,代码调用示例如下:
try {
String url = "http://www.teleye.cn";
JSONObject result = httpRequest.post(url, new JSONRequest());
boolean success = result.optBoolean("success");
if (success) {
JSONArray data = result.getJSONArray("data");
}
} catch (ServerError serverError) {
serverError.printStackTrace();
} catch (ParseError parseError) {
parseError.printStackTrace();
} catch (NetworkError networkError) {
networkError.printStackTrace();
}
RequestCallback<T>类和Request<T>抽象类所对应的代码:
public static class RequestCallback<T> {
public Request<T> request(){return null;};
public List<NameValuePair> requestParams(){return null;}
public void onPreExecute(){}
public void onPostExecute(T result){}
}
public abstract class Request<T>{
public abstract T parserResponse(byte[] responseContents) throws ParseError;
}