引用http://www.tuicool.com/articles/e2A773java
因爲項目中要使用Android調用C#寫的WebService,因而便有了這篇文章。在學習的過程當中,發如今C#中直接調用WebService方便得多,直接添加一個引用,即可以直接使用將WebService當作一個對象使用,利用Vs2010中的代碼提示功能就能爽歪歪地把想要的東西所有點出來。在Android調用,麻煩了一點,可是也還好。主要是咱們須要本身在代碼中肯定要調用WebService的方法名是什麼,要傳給WebService什麼參數以及對應的參數名,另外,一些額外的信息好比soap的版本號,也須要了解了。android
首先,讓咱們先準備一下WebService,WebService的代碼很簡單,一個是返回HelloWorld字段,另外一個是原樣返回用戶發給WebService的字符串。web
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Services; namespace testAndroidCall { /// <summary> /// WebService1 的摘要說明 /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] // 若要容許使用 ASP.NET AJAX 從腳本中調用此 Web 服務,請取消對下行的註釋。 // [System.Web.Script.Services.ScriptService] public class WebService1 : System.Web.Services.WebService { [WebMethod] public string HelloWorld() { return "Hello World"; } [WebMethod] public string EchoMessage(string msg) { return msg; } } }
接着,咱們須要下載一個Android中調用WebService的類庫c#
比較經常使用的有 Ksoap2 ,能夠從 https://code.google.com/p/wsdl2ksoap/downloads/list 進行下載。也能夠直接點這裏下載。服務器
將下載的 ksoap2-android-assembly-2.4-jar-with-dependencies.jar 包複製到Eclipse工程的lib目錄中,固然也能夠放在其餘的目錄裏。同時在Eclipse工程中引用這個jar包。網絡
(1) 在AdroidManifest.xml中加入權限 , <manifest>節點裏面加入下面這句話app
<!-- 訪問網絡的權限 --> <uses-permission android:name="android.permission.INTERNET" />
(2)、咱們在Android中創建兩個按鈕,分別對應WebService中的兩個方法異步
private void initBtn() { View btnHelloWorld = this.findViewById(R.id.btnHelloWorld); btnHelloWorld.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Map<String, String> values = new HashMap<String, String>(); values.put("msg", "這是Android手機發出的信息"); Request(METHOD_HELLO_WORLD); } }); View btnEchoMessage = this.findViewById(R.id.btnEchoMessage); btnEchoMessage.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Map<String, String> values = new HashMap<String, String>(); values.put("msg", "這是Android手機發出的信息"); Request(METHOD_ECHO_MESSAGE,values); } }); }
在Request(…)方法中,咱們主要是想實現將WebService中方法名和調用的參數傳入WebService。在這個方法中,主要應用了AsyncTask來處理WebService的調用,由於調用WebService是網絡操做,可能會比較耗時,在Android3.0以上,已經不容許在UI線程直接進行網絡操做,另外,AsyncTask還能夠直接更新UI上的控件。ide
/** * 執行異步任務 * * @param params * 方法名+參數列表(哈希表形式) */ public void Request(Object... params) { new AsyncTask<Object, Object, String>() { @Override protected String doInBackground(Object... params) { if (params != null && params.length == 2) { return CallWebService((String) params[0], (Map<String, String>) params[1]); } else if (params != null && params.length == 1) { return CallWebService((String) params[0], null); } else { return null; } } protected void onPostExecute(String result) { if (result != null) { tvMessage.setText("服務器回覆的信息 : " + result); } }; }.execute(params); }
咱們的重點將放在CallWebService()這個方法中。這個方法裏面封裝了ksoap2類庫裏面調用WebService的一些對象。佈局
(1) 指定webservice的命名空間和調用的方法名,如:
SoapObject request =new SoapObject(Namespace,MethodName);
SoapObject類的第一個參數表示WebService的命名空間,能夠從WSDL文檔中找到WebService的命名空間。第二個參數表示要調用的WebService方法名。
(2) 設置調用方法的參數值,若是沒有參數,能夠省略,設置方法的參數值的代碼以下:
Request.addProperty(「param1」,」value」);
Request.addProperty(「param2」,」value」);
要注意的是,addProperty方法的第1個參數表示調用方法的參數名,該參數值要與服務端的WebService類中的方法參數名一致,而且參數的順序一致。
(3) 生成調用Webservice方法的SOAP請求信息。該信息由SoapSerializationEnvelope對象描述,代碼爲:
SoapSerializationEnvelope envelope=new SoapSerializationEnvelope(SoapEnvelope.VER12); Envelope.bodyOut = request;
建立SoapSerializationEnvelope對象時須要經過SoapSerializationEnvelope類的構造方法設置SOAP協議的版本號。該版本號須要根據服務端WebService的版本號設置。在建立SoapSerializationEnvelope對象後,不要忘了設置SOAPSoapSerializationEnvelope類的bodyOut屬性,該屬性的值就是在第一步建立的SoapObject對象。
SOAP協議的版本號能夠從WebService的WSDL文檔(在本例中是「http://192.168.0.121/testAndroidCall/WebService1.asmx?WSDL」)
(4) 建立HttpTransportsSE對象。經過HttpTransportsSE類的構造方法能夠指定WebService的WSDL文檔的URL:
HttpTransportSE ht=new HttpTransportSE(WEB_SERVICE_URL);
WEB_SERVICE_URL 是指WebService的地址,如"http://192.168.0.121:80/testAndroidCall/WebService1.asmx?wsdl"這樣的
(5)使用call方法調用WebService方法,代碼:
ht.call(null,envelope);
Call方法的第一個參數通常爲null,第2個參數就是在第3步建立的SoapSerializationEnvelope對象。
(6)使用getResponse方法得到WebService方法的返回結果,代碼:
SoapPrimitive result = (SoapPrimitive) envelope.getResponse();
(7)最後,附上完整的CallWebService()方法
/** * 調用WebService * * @return WebService的返回值 * */ public String CallWebService(String MethodName, Map<String, String> Params) { // 一、指定webservice的命名空間和調用的方法名 SoapObject request = new SoapObject(Namespace, MethodName); // 二、設置調用方法的參數值,若是沒有參數,能夠省略, if (Params != null) { Iterator iter = Params.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); request.addProperty((String) entry.getKey(), (String) entry.getValue()); } } // 三、生成調用Webservice方法的SOAP請求信息。該信息由SoapSerializationEnvelope對象描述 SoapSerializationEnvelope envelope = new SoapSerializationEnvelope( SoapEnvelope.VER12); envelope.bodyOut = request; // c#寫的應用程序必須加上這句 envelope.dotNet = true; HttpTransportSE ht = new HttpTransportSE(WEB_SERVICE_URL); // 使用call方法調用WebService方法 try { ht.call(null, envelope); } catch (HttpResponseException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (XmlPullParserException e) { e.printStackTrace(); } try { final SoapPrimitive result = (SoapPrimitive) envelope.getResponse(); if (result != null) { Log.d("----收到的回覆----", result.toString()); return result.toString(); } } catch (SoapFault e) { Log.e("----發生錯誤---", e.getMessage()); e.printStackTrace(); } return null; }
要運行文章中的代碼,請先將WebService部署在IIS上,要保證Android手機的測試程序和WebService處在同一個局域網中。
本身實例的代碼---已成功
package com.bang.testwebservicecall;
import java.io.IOException;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.SoapFault;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpResponseException;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.support.v4.app.NavUtils;
public class MainActivity extends Activity {
TextView tvMessage;
final String METHOD_HELLO_WORLD = "TestConnection";
final String METHOD_ECHO_MESSAGE = "EchoMessage";
//服務器連接
final String WEB_SERVICE_URL = "http://192.168.1.66/web/Service.asmx?wsdl";
final String Namespace = "http://tempuri.org/";//命名空間
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initBtn();// 初始化按鈕
initTv();
}
private void initTv() {
tvMessage = (TextView) this.findViewById(R.id.tvMessage);
}
private void initBtn() {
View btnHelloWorld = this.findViewById(R.id.btnHelloWorld);
btnHelloWorld.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Map<String, String> values = new HashMap<String, String>();
values.put("msg", "這是Android手機發出的信息");
Request(METHOD_HELLO_WORLD,values);
}
});
View btnEchoMessage = this.findViewById(R.id.btnEchoMessage);
btnEchoMessage.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Map<String, String> values = new HashMap<String, String>();
values.put("msg", "這是Android手機發出的信息");
Request(METHOD_ECHO_MESSAGE, values);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
/**
* 調用WebService
*
* @return WebService的返回值
*
*/
public String CallWebService(String MethodName, Map<String, String> Params) {
// 一、指定webservice的命名空間和調用的方法名
SoapObject request = new SoapObject(Namespace, MethodName);
// 二、設置調用方法的參數值,若是沒有參數,能夠省略,
if (Params != null) {
Iterator iter = Params.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
request.addProperty((String) entry.getKey(),
(String) entry.getValue());
}
}
// 三、生成調用Webservice方法的SOAP請求信息。該信息由SoapSerializationEnvelope對象描述
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER12);
envelope.bodyOut = request;
// c#寫的應用程序必須加上這句
envelope.dotNet = true;
HttpTransportSE ht = new HttpTransportSE(WEB_SERVICE_URL);
// 使用call方法調用WebService方法
try {
ht.call(null, envelope);
} catch (HttpResponseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
try {
final SoapPrimitive result = (SoapPrimitive) envelope.getResponse();
if (result != null) {
Log.d("----收到的回覆----", result.toString());
return result.toString();
}
} catch (SoapFault e) {
Log.e("----發生錯誤---", e.getMessage());
e.printStackTrace();
}
return null;
}
/**
* 執行異步任務
*
* @param params
* 方法名+參數列表(哈希表形式)
*/
public void Request(Object... params) {
new AsyncTask<Object, Object, String>() {
@Override
protected String doInBackground(Object... params) {
if (params != null && params.length == 2) {
return CallWebService((String) params[0],
(Map<String, String>) params[1]);
} else if (params != null && params.length == 1) {
return CallWebService((String) params[0], null);
} else {
return null;
}
}
protected void onPostExecute(String result) {
if (result != null) {
tvMessage.setText("服務器回覆的信息 : " + result);
}
};
}.execute(params);
}
}