最近在項目中使用到了網絡請求,網頁數據以 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> poiInfos;
private int totalHits;
public void setPoiInfos(List<PoiInfos> poiInfos) {
this.poiInfos = poiInfos;
}
public List<PoiInfos> 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<Location> pathPoints;
public double getPathLength(){
return pathLength;
}
public void setPathLength(){
this.pathLength=pathLength;
}
public List<Location> getPathPoints (){
return pathPoints;
}
public void setPathPoints (List<Location> 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<PoiInfos> locationList) {
Type type = new TypeToken<PoiGsonBean>() {
}.getType();
Gson gson = new Gson();
PoiGsonBean poiGsonBean = gson.fromJson(strResult, type);
locationList.clear();
locationList.addAll(poiGsonBean.getPoiInfos());
}
//解析路徑導航
public void parseNavigation(String strResult, ArrayList<Location> LocationList) {
Type type = new TypeToken<PathInfos>() {
}.getType();
Gson gson = new Gson();
PathInfos pathInfos = gson.fromJson(strResult, type);
LocationList.addAll(pathInfos.getPathPoints());
}
}