上一篇文章中我們講解了App的數據統計,其主要分為兩種:使用第三方服務統計和自身實現數據統計。一般而言我們使用第三方統計服務已經可以很好的滿足我們的也無需求了,只是部分數據敏感性App,可能自身實現數據統計服務是一個更好的選擇。更多關于App數據統計相關的內容可參考我的:[Android產品研發(八)–>App數據統計](http://blog.csdn.net/qq_23547831/article/details/51598041)。
而本文中將要介紹的是App端的網絡數據解析。那么這里首先需要明確一點的是什么是數據解析呢?好吧,這里首先套用一段百度百科的定義:
> 在網絡通信過程中需要傳輸數據,常用的數據格式有兩種:JSON、XML。Cocos2d-x對JSON和XML這兩種數據格式的解析提供了支持,主要為:JOSN數據解析、XML數據解析。JOSN數據解析的過程為:首先創建JSON文件,然后在類中包含document.h和cocos-ext.h頭文件,接著通過FileUtils獲得JSON文件路徑,并通過Document對象解析JSON數據,最終獲得不同類型的數據值。XML數據解析的過程為:首先創建XML文件,接著在類中包含頭文件并使用命名文件,然后獲得XML文件全路徑,并加載XML文件,最后獲得元素并解析。
簡單而言就是App端與服務器端交互的時候約定好的內容格式。比如我們常見的Json格式,xml格式等都是數據交換格式,而現在在App開發中比較常見的網絡傳輸協議有三種:[xml](http://baike.baidu.com/link?url=HBlJ8mkEgnw9DfDiOl9oq9XhILLR9D6JFGO-xTec-4-QjOBtItP5lBGV1Eb4pHy2CyHeBf8onxir1tmqHxMoGeQMovJfGq0Dz32iV8Obn5lEbDwxMwkU5FLBOAsZdzjP),[json](http://baike.baidu.com/link?url=A5HS6n-Hqj6yvSqHP1yW_WqTWzniuDtEVFjdtFSQ6F2h1cbSsIiK21iKf7WVW1rSJ0EzGfwkVAT-CWB-yBYkt_),[protobuf](https://baike.baidu.com/item/protocol%20buffer/1664400)而我們下面將分別分析其各自的使用利弊以及解析方案。
- **數據交換格式-XML**
xml是可擴展標記語言的縮寫,常見于java web開發中,不單單作為網絡層的參數協議,還常見于各種配置文件中,在移動開發中也常見但是已不是主流的網絡傳輸協議。
優點:可讀性強,解析方便;
缺點:效率不高,資源消耗過大;
解析方式:DOM解析,SAX解析,PULL解析;
(1)DOM解析: 解析器讀入整個文檔,然后構建一個駐留內存的樹結構,然后代碼就可以使用 DOM 接口來操作這個樹結構。優點:整個文檔樹在內存中,便于操作;支持刪除、修改、重新排列等多種功能;缺點:將整個文檔調入內存(包括無用的節點),浪費時間和空間;使用場合:一旦解析了文檔還需多次訪問這些數據;硬件資源充足(內存、CPU)
(2)SAX解析: SAX ,事件驅動型解析方式。當解析器發現元素開始、元素結束、文本、文檔的開始或結束等時,發送事件,程序員編寫響應這些事件的代碼,保存數據。優點:不用事先調入整個文檔,占用資源少;SAX解析器代碼比DOM解析器代碼小,適于Applet,下載。缺點:不是持久的;事件過后,若沒保存數據,那么數據就丟了;無狀態性;從事件中只能得到文本,但不知該文本屬于哪個元素;使用場合:Applet;只需XML文檔的少量內容,很少回頭訪問;機器內存少;
(3)PULL解析: PULL解析方式是android專門為移動設備上解析XML文件而設計的一種解析方式,顯而易見的其更加適用于移動設備解析xml文件。Pull解析和Sax解析很相似,Pull解析和Sax解析不一樣的地方是pull讀取xml文件后觸發相應的事件調用方法返回的是數字還有pull可以在程序中控制想解析到哪里就可以停止解析。
- **數據交換格式-JSON**
JSON是一種輕量級的數據交換格式,它較xml格式更叫的簡單和“小”,因此比xml更適合移動端對流量和內存的控制。
優點:較XML格式更加小巧;
缺點:傳輸效率也不是太別高,但相較于xml提高了很多;
解析方式:Gson解析,JSONObject方式解析,FastJson解析
(1)Gson解析: Gson解析方式是Google開源的一套解析方式,通過提供的Gson jar包,通過靜態方法直接由字符串解析成java對象,簡單方便。
具體使用方法,可參考:[Google Gson 使用簡介](http://www.cnblogs.com/haippy/archive/2012/05/20/2509329.html)
(2)JSONObject解析: JSONObject在org.json下面的包中,其也是一個解析Json字符串的工具類,
具體使用方式可參考:[JSONObject與JSONArray的使用](http://www.cnblogs.com/xwdreamer/archive/2011/12/16/2296904.html)
(3)FastJson解析: FastJson是阿里巴巴開源的一個解析Json數據的類庫,能夠將json字符串解析成java對象。這里有其介紹,英文水平不好就不獻丑了...
* Provide best performance in server side and android client.
* Provide simple toJSONString() and parseObject() methods to convert Java objects to JSON and vice-versa
* Allow pre-existing unmodifiable objects to be converted to and from JSON
* Extensive support of Java Generics
* Allow custom representations for objects
* Support arbitrarily complex objects (with deep inheritance hierarchies and extensive use of generic types)
**數據交換格式-ProtoBuf**
protocolbuffer(以下簡稱PB)是google 的一種數據交換的格式,它獨立于語言,獨立于平臺。google 提供了多種語言的實現:java、c#、c++、go 和 python,每一種實現都包含了相應語言的編譯器以及庫文件。由于它是一種二進制的格式,比使用 xml 進行數據交換快許多。可以把它用于分布式應用之間的數據通信或者異構環境下的數據交換。作為一種效率和兼容性都很優秀的二進制數據傳輸格式,可以用于諸如網絡傳輸、配置文件、數據存儲等諸多領域。
優點:傳輸效率快(比xml和json快10-20倍),文檔型協議;
缺點:使用不太方便;
這里簡單解釋一下什么是文檔型協議,向我們的xml和json一般在使用的時候都需要保存一份說明文檔和一個實際的java類,而protobuf在使用的時候其定義的格式就是說明文檔,簡單明了而且可以將其編譯成各個平臺的類庫,以java平臺為例,其編程成jar之后,若定義文件發生了變化,則在使用jar包的話就會報錯,必須重新編譯,這也就保證了App端與服務器端的協議統一性。
**網絡數據解析實踐**
由于ProtoBuf的傳輸效率和文檔型協議的特性,公司產品選擇了Protobuf作為網絡數據解析的工具。下面我就以一個簡單的登錄操作,介紹一下對ProtoBuf的實際應用。
(1)定義ProtoBuf文件

(2)定義登錄網絡操作請求接口
~~~
// 提交短信驗證碼,如果該手機號碼沒有注冊過,則直接給用戶注冊
message SmsLogin {
message Request {
required string phone = 1; // 手機號碼
required string verifyCode = 2; // 驗證碼
}
message Response {
/*
* 0:成功;-1:登錄失敗;-2:驗證碼錯誤;-3:驗證碼已經失效;-4:手機號碼格式不正確;-5:不是內測用戶不能登錄
*/
required int32 ret = 1;
optional com.uu.facade.passport.pb.bean.UserAppSessionTicket sessionTicket = 2;
optional string phone = 3; // 手機號碼
optional string imgUrl = 4; // 用戶圖像url
optional com.uu.facade.base.common.UserStatus userStatus = 5; // 用戶狀態
}
}
~~~
可以看到在Protobuf中定義網絡請求,分為兩個部分,請求部分和應答部分,其message request定義的是請求信息,而message response定義的是應答信息。
請求信息中的字段就是我們請求中需要傳遞的字段,應答信息中的字段就是App端獲取的服務器端的應答信息集合。
每個字段都有修飾符,那么修飾符是做什么的呢?
在protobuf中定義了三種修飾符,分別為:required,optional,repeated。其中:
* required:表示的是這個字段必須要傳遞,不可為空;
* optional:表示的是這個字段可傳可不傳,可以為空;
* repeated:表示這個字段傳遞的是列表數據
在message的定義過程中,message還可以嵌套另外的message信息,比如應答信息中的UserStatus,其和java中對象的概念很類似。
(3)將proto文件編譯成jar包 這里就不在具體介紹怎么講proto文件編譯成jar了,google已經提供了相應的編譯工具。
(4)在android代碼中使用 由于我們將proto文件編譯成了jar包,首先我們需要將jar引入到我們的工程,然后就可以使用了。這里簡單看一下具體的使用代碼。
~~~
/**
* 請求服務器短信登陸
*
* @param phone
* @param code
*/
private void requestSmsLogin(String phone, String code) {
showProgress(false);// 顯示進度條
LoginInterface.SmsLogin.Request.Builder request = LoginInterface.SmsLogin.Request.newBuilder();
request.setPhone(phone); // 設置手機號
request.setVerifyCode(code); // 設置驗證碼
NetworkTask task = new NetworkTask(Cmd.CmdCode.SmsLogin_SSL_VALUE);
task.setBusiData(request.build().toByteArray());
NetworkUtils.executeNetwork(task, new HttpResponse.NetWorkResponse<UUResponseData>() {
@Override
public void onSuccessResponse(UUResponseData responseData) {
if (responseData.getRet() == 0) {
try {
// 顯示通用下發消息
showResponseCommonMsg(responseData.getResponseCommonMsg());
// 解析請求應答信息
LoginInterface.SmsLogin.Response response = LoginInterface.SmsLogin.Response.parseFrom(responseData.getBusiData());
// 判斷是否請求成功
if (response.getRet() == 0) {
...doSomeThing()...
}
} catch (Exception e) {
e.printStackTrace();
showDefaultNetworkSnackBar();
}
}
}
@Override
public void onError(VolleyError errorResponse) {
showDefaultNetworkSnackBar();
}
@Override
public void networkFinish() {
// 取消進度條顯示
dismissProgress();
}
});
}
~~~
可以發現我們在代碼中直接有對應的登錄請求message類,這樣我們就可以直接通過java類調用了,O(∩_∩)O哈哈~。
**總結**:
xml,json,protobuf三種不同的網絡數據交換格式各有利弊,大家在選擇的時候可以根據具體的產品需求來確定到底選擇哪一個,當然了這里我還是比較推薦protobuf的。
[android產品研發(一)-->實用開發規范 ](http://blog.csdn.net/qq_23547831/article/details/51534013)
[android產品研發(二)-->啟動頁優化 ](http://blog.csdn.net/qq_23547831/article/details/51541277)
[android產品研發(三)-->基類Activity ](http://blog.csdn.net/qq_23547831/article/details/51546974)
[android產品研發(四)-->減小Apk大小](http://blog.csdn.net/qq_23547831/article/details/51559066)
[android產品研發(五)-->多渠道打包](http://blog.csdn.net/qq_23547831/article/details/51569261)
[Android產品研發(六)–>Apk混淆](http://blog.csdn.net/qq_23547831/article/details/51581491)
[android產品研發(七)-->Apk熱修復](http://blog.csdn.net/qq_23547831/article/details/51587927)
[Android產品研發(八)–>App數據統計](http://blog.csdn.net/qq_23547831/article/details/51612429)
- 前言
- (一)–>實用開發規范
- (二)-->啟動頁優化
- (三)-->基類Activity
- (四)-->減小Apk大小
- (五)-->多渠道打包
- (六)-->Apk混淆
- (七)-->Apk熱修復
- (八)-->App數據統計
- (九)-->App網絡數據解析
- (十)-->盡量不使用靜態變量保存數據
- (十一)-->應用內跳轉Scheme協議
- (十二)-->App長連接實現
- (十三)-->App輪詢操作
- (十四)-->App升級與更新
- (十五)-->內存對象序列化
- (十六)-->開發者選項
- (十七)-->Hybrid開發
- (十八)-->webview問題集錦
- (十九)-->Android studio中的單元測試
- (二十)-->代碼Review
- (二十一)-->Android中的UI優化
- (二十二)-->Android實用調試技巧
- (二十三)-->Android中保存靜態秘鑰實踐
- (二十四)-->內存泄露場景與檢測
- (二十五)-->MVC/MVVM/MVP簡單理解