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。
希望對大家有所幫助。
貼一下解析程式碼: