因为项目中要使用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>节点里面加入下面这句话异步
<!-- 访问网络的权限 --> <uses-permission android:name="android.permission.INTERNET" />
(2)、咱们在Android中创建两个按钮,分别对应WebService中的两个方法ide
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上的控件。布局
/** * 执行异步任务 * * @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处在同一个局域网中。