1. 程式人生 > >Android 呼叫.Net WCF服務

Android 呼叫.Net WCF服務

本來以為在java平臺上用axis2生成了客戶端代理類然後移植到Android平臺上就好了。沒想到在移植過程中出現了很多問題。說明JVM和android的DVM差距還是很大的。

JVM執行的是class檔案,而DVM執行的是dex檔案。

在eclipse裡面開發Android程式的時候在編譯時會把jar包裡面的class一個個編譯成DVM可執行的dex檔案。當然,有個前提是jar包是放在source folder裡面的。這樣eclipse才會在編譯程式的時候將jar包編譯到apk檔案中去。要不然雖然本地eclipse不會報錯,但是在模擬器中會報錯NoClassDefFound。

而且有的jar包是不能被dexdump.exe正確轉換成dex檔案的。這樣就導致這個jar包不能用,後果是整個程式都不能正確執行。

我在將axis2移植到Android平臺上去的時候有一些jar包轉換不了。然後網上找了很多資料,都沒人解決這個問題。希望如果有人解決了能共享一下下。

後來實在不行了,看網上說在Android平臺都用ksoap2來呼叫Web Service。自己覺得解決不了axis2的問題。於是只能改變方向。學習了一下ksoap2。在ksoap2呼叫WCF服務的時候也出現了很多問題。好在後來慢慢都解決了。現在將我遇到的問題和解決的方案都寫下來,供其他也碰到這些問題的人蔘考。

下面列舉一下我碰到的問題和解決方案

1.呼叫是引數的說明

 

Namespace 是你設定的服務名稱空間,一般沒有設定就是http://tempuri.org/

URL是你服務暴露的地址,通過這個地址可以獲取wsdl。在android裡面127.0.0.1代表的是模擬器的地址,而10.0.0.2代表的才是電腦的127.0.0.1。所以如果是自己本機做WCF伺服器的話,程式裡面應該這麼設定。

SOAP_ACTION是你的wsdl裡面相對應的方法的地址。

MethodName就是SOAP_ACTION最後面的那個指明ACTION的方法名。

2.引數傳遞 複雜物件

服務裡面不可避免的是會傳遞引數,但是在可能在wcf服務端可能解析不了你傳的引數。通過tcptrace擷取soap後發現是引數的namespace不對應的原因。下面是一個例子

服務端程式碼:

 

User類:

 

android客戶端程式碼如下:

 

android端也有一個User類,這個類是繼承的BaseObject,BaseObject實現KvmSerializable介面

先BaseObject:

 

然後是User類

 

因為要序列化啊什麼什麼的,解釋起來比較煩。這邊也不解釋了。大家有興趣可以去查一下。只說明一下是通過info.namespace+info.name來反序列化的。

3.如果有證書加密,會一直說timeout。

解決方法是在android客戶端呼叫下面這個方法。這個方法要在httptransport.call()之前呼叫

類是這麼寫的:

 

這個信任一切證書。應為自制的證書是不被信任的,所以shakehand的時候一直timeout。

4.wcf設定的自定義帳號密碼認證(userNameAuthentication  )

加入這個之後要在soap傳送前在head裡面加入使用者資訊。

加入的方法是:

 

這個需要重寫httptransport的getServiceConnection()方法。

因為在呼叫httptransport.call()的時候Connection才被初始化,所以在程式外getServiceConnection().setRequestProperty()會報錯說nullpoint。

希望對大家有所幫助。

貼一下解析程式碼: