Android使用ksoap2-android調用WebService學習

        以前主要作客戶端UI交互,不多處理數據和接觸服務端,但如今的移動設備根本不可能離得開網絡鏈接,數據的交換。最近學習的是在android端如何去調用遠程WebService,都說WebService是一種基於SOAP協議的遠程調用標準,對於這個協議理解不深,知道webservice能夠將不一樣操做系統平臺、不一樣語言、不一樣技術整合到一塊,android SDK沒有直接調用webservice的庫,最經常使用的是藉助ksoap2-android這個第三方SDK,點擊打開連接,而後和其餘第三方jar包同樣導入android項目中便可。java

        對於WebService服務器具體的編寫,現階段本身不瞭解,暫且使用網絡免費的WebService進行學習http://www.webxml.com.cn/zh_cn/index.aspx,利用這個來寫一個簡單的國內天氣預報的查詢,代碼編寫參照《瘋狂Android講義》相關部分,本身作部分修改。android

 

-------------------------------------------------------------------------------------------------------------web

       如下是幾個主要的方法:安全

1.建立HttpTransportSE傳輸對象:HttpTransportSE ht = new HttpTransportSE(SERVICE_URL); SERVICE_URL是webservice提供服務的url服務器

2.使用SOAP1.1協議建立Envelop對象:SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); 設置SOAP協議的版本號,根據服務端WebService的版本號設置。網絡

3.實例化SoapObject對象:SoapObject soapObject = new SoapObject(SERVICE_NAMESPACE, methodName); 第一個參數表示WebService的命名空間,能夠從WSDL文檔中找到WebService的命名空間。第二個參數表示要調用的WebService方法名。多線程

4.設置調用方法的參數值,若是沒有參數,能夠省略:例如soapObject.addProperty("theCityCode", cityName);異步

5.記得設置bodyout屬性 envelope.bodyOut = soapObject;ide

6.調用webservice:ht.call(SERVICE_NAMESPACE+methodName, envelope);svn

7.獲取服務器響應返回的SOAP消息:

     SoapObject result = (SoapObject) envelope.bodyIn;
     SoapObject detail = (SoapObject) result.getProperty(methodName+"Result");

 

-------------------------------------------------------------------------------------------------------------

 

在這個天氣預報的demo中須要屢次調用webservice,將方法寫在一個工具類中,代碼以下:

package com.example.webservicedemo;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.SoapFault;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;

public class WebServiceUtil {
	// 定義webservice的命名空間
	public static final String SERVICE_NAMESPACE = "http://WebXml.com.cn/";
	// 定義webservice提供服務的url
	public static final String SERVICE_URL = "http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx";

	// 調用遠程webservice獲取省份列表
	public static List<String> getProvinceList() {
		// 調用 的方法
		String methodName = "getRegionProvince";
		// 建立HttpTransportSE傳輸對象
		HttpTransportSE ht = new HttpTransportSE(SERVICE_URL);
		try {
			ht.debug = true;
			// 使用SOAP1.1協議建立Envelop對象
			SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
					SoapEnvelope.VER11);
			// 實例化SoapObject對象
			SoapObject soapObject = new SoapObject(SERVICE_NAMESPACE,
					methodName);
			envelope.bodyOut = soapObject;
			// 設置與.NET提供的webservice保持較好的兼容性
			envelope.dotNet = true;

			// 調用webservice
			ht.call(SERVICE_NAMESPACE + methodName, envelope);
			if (envelope.getResponse() != null) {
				// 獲取服務器響應返回的SOAP消息
				SoapObject result = (SoapObject) envelope.bodyIn;
				SoapObject detail = (SoapObject) result.getProperty(methodName
						+ "Result");
				// 解析服務器響應的SOAP消息
				return parseProvinceOrCity(detail);
			}
		} catch (SoapFault e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (XmlPullParserException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	// 根據省份獲取城市列表
	public static List<String> getCityListsByProvince(String province) {
		// 調用的方法
		String methodName = "getSupportCityString";
		// 建立httptransportSE傳輸對象
		HttpTransportSE ht = new HttpTransportSE(SERVICE_URL);
		ht.debug = true;
		// 實例化SoapObject對象
		SoapObject soapObject = new SoapObject(SERVICE_NAMESPACE, methodName);
		// 添加一個請求參數
		soapObject.addProperty("theRegionCode", province);
		// 使用soap1.1協議建立envelop對象
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
				SoapEnvelope.VER11);
		envelope.bodyOut = soapObject;
		// 設置與.NET提供的webservice保持較好的兼容性
		envelope.dotNet = true;

		// 調用webservice
		try {
			ht.call(SERVICE_NAMESPACE + methodName, envelope);
			if (envelope.getResponse() != null) {
				// 獲取服務器響應返回的SOAP消息
				SoapObject result = (SoapObject) envelope.bodyIn;
				SoapObject detail = (SoapObject) result.getProperty(methodName
						+ "Result");
				// 解析服務器響應的SOAP消息
				return parseProvinceOrCity(detail);
			}
		} catch (SoapFault e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (XmlPullParserException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	// 解析省份或城市
	public static List<String> parseProvinceOrCity(SoapObject detail) {
		ArrayList<String> result = new ArrayList<String>();
		for (int i = 0; i < detail.getPropertyCount(); i++) {
			// 解析出每一個省份
			result.add(detail.getProperty(i).toString().split(",")[0]);
		}
		return result;
	}

	// 根據城市字符串獲取相應天氣狀況
	public static SoapObject getWeatherByCity(String cityName) {
		String methodName = "getWeather";
		HttpTransportSE ht = new HttpTransportSE(SERVICE_URL);
		ht.debug = true;
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
				SoapEnvelope.VER11);
		SoapObject soapObject = new SoapObject(SERVICE_NAMESPACE, methodName);
		soapObject.addProperty("theCityCode", cityName);
		envelope.bodyOut = soapObject;
		envelope.dotNet = true;

		try {
			ht.call(SERVICE_NAMESPACE + methodName, envelope);
			SoapObject result = (SoapObject) envelope.bodyIn;
			SoapObject detail = (SoapObject) result.getProperty(methodName
					+ "Result");
			return detail;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (XmlPullParserException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

}



 

上面這個即是主要實現遠程調用webservice的代碼,其餘實如今activity中完成便可,可是這裏也會涉及到一個問題,就是Android多線程問題,在調用webservice時,爲了防止ANR的出現,不能在主線程中進行,須要另開子線程執行,,由於子線程涉及到UI更新,Android主線程是線程不安全的,也就是說,更新UI只能在主線程中更新,子線程中操做是危險的.便要涉及Handler的使用了,實在是不才,本身更多時候習慣使用AsyncTask來代替Handler(仍是要從新琢磨下Handler的使用方法),由於操做起來比較簡單方便,下面是項目中異步操做類中的一個:

 

package com.example.webservicedemo;

import java.util.List;
import android.os.AsyncTask;
import android.widget.Spinner;

public class ProvinceAsyncTask extends AsyncTask<String, String, List<String>> {
	private MainActivity activity;
	private List<String> provinces;
	private Spinner sp_province;
	
	public ProvinceAsyncTask (MainActivity activity,Spinner sp_province){
		this.activity = activity;
		this.sp_province = sp_province;
	}

	@Override
	protected List<String> doInBackground(String... params) { 
		// TODO Auto-generated method stub
		provinces = WebServiceUtil.getProvinceList();
		return null;
	}

	@Override
	protected void onPostExecute(List<String> result) {
		// TODO Auto-generated method stub
		ListAdapter adapter = new ListAdapter(activity, provinces);
		sp_province.setAdapter(adapter);
		
	}
}



能夠看出來比較簡單,在doInBackground中執行調用webservice,在onPostExecute中執行列表刷新展現

 

 

最後附上該demo的代碼,但願能夠對初涉及android調用webservice的朋友有幫助

http://download.csdn.net/detail/eyu8874521/5609627

相關文章
相關標籤/搜索