最近在项目中使用到了网络请求,网页数据以 json的方式返回,所以也避免不了json解析。众所周知,android为防止UI 阻塞,所以耗时操作时候都需要用户异步的方式处理。虽然进行了异步处理,但是速度上还是应该尽可能快。最后分析得出–HttpURLConnection+GSON解析最优。
一: 网络请求 httpClient or HttpURLConnection
在Android 2.3及以上版本,使用的是HttpURLConnection,而在Android2.2及以下版本,使用的是HttpClient。至于为什么新版本为什么不推荐使用,则是谷歌对其不怎么更新,支持不太高。
HttpURLConnection是一种多用途、轻量极的HTTP客户端,使用它来进行HTTP操作可以适用于大多数的应用程序。虽然HttpURLConnection的API提供的比较简单,但是同时这也使得我们可以更加容易地去使用和扩展它。
但是如果不是简单网页,比如需要登录后与服务器保持连接的话,还是推荐使用httpClient,通过set-cookies方式。
这些都是比较书面化的定义,在实际的项目中测试了一下速度。httpURLConnect会更快一些,毕竟是读取字节流的方式读取json信息。
// httpClient Get
public static String connServerResult(String strUrl) {
// 请求服务器的URL地址
// 返回数据转换成String
HttpGet httpRequest = new HttpGet(strUrl);
String strResult = null;
try {
HttpClient httpClient = new DefaultHttpClient();
HttpResponse httpResponse = httpClient.execute(httpRequest);
int code = httpResponse.getStatusLine().getStatusCode();
if (code == HttpStatus.SC_OK) {
Log.v("lzw", "PoiSearch-connServerResult-1");
strResult = EntityUtils.toString(httpResponse.getEntity());
}
} catch (Exception e) {
}
return strResult;
}
//httpURlConnect 采用回调方式处理异步事件
public static void getHttpResponse(final String allConfigUrl) {
new Thread(new Runnable() {
public void run() {
BufferedReader in = null;
StringBuffer result = null;
HttpURLConnection connection = null;
try {
URL url = new URL(allConfigUrl);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Charset", "utf-8");
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
result = new StringBuffer();
// 读取URL的响应
in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result.append(line);
}
Message msg_navigation = mHandler.obtainMessage();
msg_navigation.what = 0;
msg_navigation.obj = result.toString();
mHandler.sendMessage(msg_navigation);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (connection != null) {
connection.disconnect();
connection = null;
}
if (in != null) {
in.close();
in = null;
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}).start();
}
//执行回调函数,处理异步事件。
public static void doHttpUtilsCallBaockListener(final HttpUtilsCallbackListener listener) {
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0:
String str = (String) msg.obj;
listener.success(str);
break;
default:
break;
}
}
};
}
public interface HttpUtilsCallbackListener {
void success(String str);
}
经过上面两种方式,对我请求的一个路径导航的网页,httpClient大概3385ms httpURLConncet 2025ms。同等情况下 httpURLConnect性能更优。
二. JSON解析。
测试一个北京到上海的路径导航API网页数据,大约json里面坐标数组几万个,此时良好的解析方式将会凸显出性能的优劣。
我在处理json解析的时候用到三种方式;
第一种 传统android自带的解析方式,使用JSONObject 解析对象, JSONArray 解析数组。
第二种 阿里巴巴开源提供的fastjson.
第三种 谷歌提供的GSON。
实际在几万个数据的解析下 谷歌GSON解析更胜一筹,领先fastjson 几秒,最慢也是自带的 JSONObject .
最后附上GSON解析相关类。fastjson 和传统JSONObject 将不再赘述。
//PoiGsonBean 类
public class PoiGsonBean {
private List poiInfos;
private int totalHits;
public void setPoiInfos(List poiInfos) {
this.poiInfos = poiInfos;
}
public List getPoiInfos() {
return this.poiInfos;
}
public void setTotalHits(int totalHits) {
this.totalHits = totalHits;
}
public int getTotalHits() {
return this.totalHits;
}
public static class PoiInfos {
private String address;
private Location location;
private String name;
private int score;
private String telephone;
private String uid;
public void setAddress(String address) {
this.address = address;
}
public String getAddress() {
return this.address;
}
public void setLocation(Location location) {
this.location = location;
}
public Location getLocation() {
return this.location;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setScore(int score) {
this.score = score;
}
public int getScore() {
return this.score;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
public String getTelephone() {
return this.telephone;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getUid() {
return this.uid;
}
}
public class PathInfos {
public double pathLength;
public List pathPoints;
public double getPathLength(){
return pathLength;
}
public void setPathLength(){
this.pathLength=pathLength;
}
public List getPathPoints (){
return pathPoints;
}
public void setPathPoints (List pathPoints){
this.pathPoints=pathPoints;
}
}
public static class Location {
private double x;
private double y;
public void setX(double x) {
this.x = x;
}
public double getX() {
return this.x;
}
public void setY(double y) {
this.y = y;
}
public double getY() {
return this.y;
}
}
public static class Junction {
private double x;
private double y;
public void setX(double x) {
this.x = x;
}
public double getX() {
return this.x;
}
public void setY(double y) {
this.y = y;
}
public double getY() {
return this.y;
}
}
}
//json解析类
public class JsonPara {
//解析POI
public void parsePOI(String strResult, ArrayList locationList) {
Type type = new TypeToken() {
}.getType();
Gson gson = new Gson();
PoiGsonBean poiGsonBean = gson.fromJson(strResult, type);
locationList.clear();
locationList.addAll(poiGsonBean.getPoiInfos());
}
//解析路径导航
public void parseNavigation(String strResult, ArrayList LocationList) {
Type type = new TypeToken() {
}.getType();
Gson gson = new Gson();
PathInfos pathInfos = gson.fromJson(strResult, type);
LocationList.addAll(pathInfos.getPathPoints());
}
}