SERVICE_NAMESPACE
// final SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
// envelope.dotNet=false;
// envelope.addMapping(ENCODED_TYPES_NAMESPACE, "User", User.class);
當你想使用ksoap2從服務端遞複雜物件給android 用戶端時,下面的代碼可以協助你。這是我尋找了兩天,終於找到的解決方案,期間的辛苦與煩惱就不提了。遺憾網上竟沒有一個完整的部落格說明這點,有點是提供大致的方案,然而一些沒有提到的小細節往往絆住了你前進的腳步,屢次失敗的嘗試不斷的打擊著你的信心,令你灰心喪氣,功虧一簣。
下面貼出代碼,大家可以參考下,這些代碼是我編譯通過並可以成功啟動並執行。
眾所周知,ksoap2 已經預設實現了基本類型(string, int , float,double)資料的類型的序列化傳輸,就是你不需要手動序列化這些基本類型資料,ksoap已經幫你實現了。然而對於複雜類型對象的傳輸,我們必須瞭解下它的傳輸原理:
1. 當傳輸的是arraylist<基本類型> 對象時,你只要把它當做基本類型資料來傳就是了,我們可以在瀏覽器中查看服務端函數的返回形式,可以看到次種傳輸的返回結果是<return>值1</return> <return>值2</return> <return>值3</return>。由此可以看到返回數組的結果形式是由多個相同節點名組成的xml,因此我們只需要在用戶端用
if (envelope.getResponse() != null) {
SoapObject result = (SoapObject) envelope.bodyIn; 這句和下面一句,這兩句代碼就能幫你擷取list的元素值了。
textView_result.setText(result.getProperty(0).toString()); 0 表示數組的第1個元素值
textView_result.setText(result.toString());
} else { }
2. 當傳輸的是類對象時,且類對象的屬性值都是是基礎資料型別 (Elementary Data Type),這與上面的原理基本相似,其代碼如下:
if (envelope.getResponse() != null) {
SoapObject result = new SoapObject(serviceUrl,"NetData");
result = (SoapObject) envelope.getResult(); //這裡如果用bodyin是不行的,拋出異常。
String nd = result.getProperty("name").toString(); //執行服務端的類屬性值的名稱
textView_result.setText(nd.toString());
} else { }
3. 當傳輸任意資料類型時,可以將其封裝為類,再把它序列化為byte數組進行傳輸,在另一端進行還原序列化為類對象,這樣就可以用該對象訪問類裡所有成員變數了。其參考代碼串連:http://www.cublog.cn/u1/47207/showart_1864609.html。該文章講得很詳細,可以按照它來編寫,但有一點需要注意,
byte[] by = (byte[])Response; 這行代碼,在我運行時拋出異常,我不明白作者是怎麼能成功啟動並執行。經過辛苦找尋,終於找到瞭解決的辦法,其可行代碼是:
Object result =(Object)envelope.getResult();
String retString = String.valueOf(result);
byte[] retByte = org.kobjects.base64.Base64.decode(retString);
DataPacket Dp = DataPacket.deserialize(retByte);
擷取的object轉換為位元組數組時,需要通過解碼,再還原序列化。真不明白參考代碼串連那篇文章的作者怎麼沒有說明這點,難道他不用解碼也可以運行成功,還是忽略寫了這點的重要性。