由于项目中要使用Android调用C#写的WebService,于是便有了这篇文章。在学习的过程中,发现在C#中直接调用WebService方便得多,直接添加一个引用,便可以直接使用将WebService当做一个对象使用,利用Vs2010中的代码提示功能就能爽歪歪地把想要的东西全部点出来。在Android调用,麻烦了一点,但是也还好。主要是我们需要自己在代码中确定要调用WebService的方法名是什么,要传给WebService什么参数以及对应的参数名,另外,一些额外的信息比如soap的版本号,也需要了解了。

1.准备工作:写一个测试用的WebService

首先,让我们先准备一下WebService,WebService的代码很简单,一个是返回HelloWorld字段,另一个是原样返回用户发给WebService的字符串。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.Web.Services;
  6.  
  7. namespace testAndroidCall
  8. {
  9. /// <summary>
  10. /// WebService1 的摘要说明
  11. /// </summary>
  12. [WebService(Namespace = "http://tempuri.org/")]
  13. [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
  14. [System.ComponentModel.ToolboxItem(false)]
  15. // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。
  16. // [System.Web.Script.Services.ScriptService]
  17. public class WebService1 : System.Web.Services.WebService
  18. {
  19.  
  20. [WebMethod]
  21. public string HelloWorld()
  22. {
  23. return "Hello World";
  24. }
  25. [WebMethod]
  26. public string EchoMessage(string msg)
  27. {
  28. return msg;
  29. }
  30. }
  31. }

接着,我们需要下载一个Android中调用WebService的类库

比较常用的有Ksoap2,可以从https://code.google.com/p/wsdl2ksoap/downloads/list进行下载。也可以直接点这里下载

将下载的ksoap2-android-assembly-2.4-jar-with-dependencies.jar包复制到Eclipse工程的lib目录中,当然也可以放在其他的目录里。同时在Eclipse工程中引用这个jar包。

2、完成简单的Android布局代码的编写

(1) 在AdroidManifest.xml中加入权限,<manifest>节点里面加入下面这句话

  1. <!-- 访问网络的权限 -->
  2.  
  3. <uses-permission android:name="android.permission.INTERNET" />

(2)、我们在Android中建立两个按钮,分别对应WebService中的两个方法

  1. private void initBtn() {
  2. View btnHelloWorld = this.findViewById(R.id.btnHelloWorld);
  3. btnHelloWorld.setOnClickListener(new OnClickListener() {
  4.  
  5. @Override
  6. public void onClick(View v) {
  7.  
  8. Map<String, String> values = new HashMap<String, String>();
  9. values.put("msg", "这是Android手机发出的信息");
  10. Request(METHOD_HELLO_WORLD);
  11. }
  12. });
  13.  
  14. View btnEchoMessage = this.findViewById(R.id.btnEchoMessage);
  15. btnEchoMessage.setOnClickListener(new OnClickListener() {
  16. @Override
  17. public void onClick(View v) {
  18. Map<String, String> values = new HashMap<String, String>();
  19. values.put("msg", "这是Android手机发出的信息");
  20. Request(METHOD_ECHO_MESSAGE,values);
  21. }
  22. });
  23. }

在Request(…)方法中,我们主要是想实现将WebService中方法名和调用的参数传入WebService。在这个方法中,主要应用了AsyncTask来处理WebService的调用,因为调用WebService是网络操作,可能会比较耗时,在Android3.0以上,已经不允许在UI线程直接进行网络操作,另外,AsyncTask还可以直接更新UI上的控件。

  1. /**
  2. * 执行异步任务
  3. *
  4. * @param params
  5. * 方法名+参数列表(哈希表形式)
  6. */
  7. public void Request(Object... params) {
  8. new AsyncTask<Object, Object, String>() {
  9.  
  10. @Override
  11. protected String doInBackground(Object... params) {
  12. if (params != null && params.length == 2) {
  13. return CallWebService((String) params[0],
  14. (Map<String, String>) params[1]);
  15. } else if (params != null && params.length == 1) {
  16. return CallWebService((String) params[0], null);
  17. } else {
  18. return null;
  19. }
  20. }
  21.  
  22. protected void onPostExecute(String result) {
  23. if (result != null) {
  24. tvMessage.setText("服务器回复的信息 : " + result);
  25. }
  26. };
  27.  
  28. }.execute(params);
  29. }

3、分析Android调用WebService的代码

我们的重点将放在CallWebService()这个方法中。这个方法里面封装了ksoap2类库里面调用WebService的一些对象。

(1) 指定webservice的命名空间和调用的方法名,如:

  1. SoapObject request =new SoapObject(Namespace,MethodName);

SoapObject类的第一个参数表示WebService的命名空间,可以从WSDL文档中找到WebService的命名空间。第二个参数表示要调用的WebService方法名。

(2) 设置调用方法的参数值,如果没有参数,可以省略,设置方法的参数值的代码如下:

  1. Request.addProperty(“param1”,”value”);
  2. Request.addProperty(“param2”,”value”);

要注意的是,addProperty方法的第1个参数表示调用方法的参数名,该参数值要与服务端的WebService类中的方法参数名一致,并且参数的顺序一致。

(3) 生成调用Webservice方法的SOAP请求信息。该信息由SoapSerializationEnvelope对象描述,代码为:

  1. SoapSerializationEnvelope envelope=new SoapSerializationEnvelope(SoapEnvelope.VER12);
  2. Envelope.bodyOut = request;

创建SoapSerializationEnvelope对象时需要通过SoapSerializationEnvelope类的构造方法设置SOAP协议的版本号。该版本号需要根据服务端WebService的版本号设置。在创建SoapSerializationEnvelope对象后,不要忘了设置SOAPSoapSerializationEnvelope类的bodyOut属性,该属性的值就是在第一步创建的SoapObject对象。

注:

  1. SOAP协议的版本号可以从WebServiceWSDL文档(在本例中是“http://192.168.0.121/testAndroidCall/WebService1.asmx?WSDL”)

(4) 创建HttpTransportsSE对象。通过HttpTransportsSE类的构造方法可以指定WebService的WSDL文档的URL:

  1. HttpTransportSE ht=new HttpTransportSE(WEB_SERVICE_URL);

WEB_SERVICE_URL是指WebService的地址,如"http://192.168.0.121:80/testAndroidCall/WebService1.asmx?wsdl"这样的

(5)使用call方法调用WebService方法,代码:

  1. ht.callnullenvelope);

Call方法的第一个参数一般为null,第2个参数就是在第3步创建的SoapSerializationEnvelope对象。

(6)使用getResponse方法获得WebService方法的返回结果,代码:

  1. SoapPrimitive result = (SoapPrimitive) envelope.getResponse();

(7)最后,附上完整的CallWebService()方法

  1. /**
  2. * 调用WebService
  3. *
  4. * @return WebService的返回值
  5. *
  6. */
  7. public String CallWebService(String MethodName, Map<String, String> Params) {
  8. // 1、指定webservice的命名空间和调用的方法名
  9.  
  10. SoapObject request = new SoapObject(Namespace, MethodName);
  11. // 2、设置调用方法的参数值,如果没有参数,可以省略,
  12. if (Params != null) {
  13. Iterator iter = Params.entrySet().iterator();
  14. while (iter.hasNext()) {
  15. Map.Entry entry = (Map.Entry) iter.next();
  16. request.addProperty((String) entry.getKey(),
  17. (String) entry.getValue());
  18. }
  19. }
  20. // 3、生成调用Webservice方法的SOAP请求信息。该信息由SoapSerializationEnvelope对象描述
  21. SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
  22. SoapEnvelope.VER12);
  23. envelope.bodyOut = request;
  24. // c#写的应用程序必须加上这句
  25. envelope.dotNet = true;
  26. HttpTransportSE ht = new HttpTransportSE(WEB_SERVICE_URL);
  27. // 使用call方法调用WebService方法
  28. try {
  29. ht.call(null, envelope);
  30. } catch (HttpResponseException e) {
  31. e.printStackTrace();
  32. } catch (IOException e) {
  33. e.printStackTrace();
  34. } catch (XmlPullParserException e) {
  35. e.printStackTrace();
  36. }
  37. try {
  38. final SoapPrimitive result = (SoapPrimitive) envelope.getResponse();
  39. if (result != null) {
  40. Log.d("----收到的回复----", result.toString());
  41. return result.toString();
  42. }
  43.  
  44. } catch (SoapFault e) {
  45. Log.e("----发生错误---", e.getMessage());
  46. e.printStackTrace();
  47. }
  48. return null;
  49. }

4、运行代码

要运行文章中的代码,请先将WebService部署在IIS上,要保证Android手机的测试程序和WebService处在同一个局域网中。

示例代码

Android端源代码

WebService源代码

在Android中调用C#写的WebService(附源代码)的更多相关文章

  1. 在Android中调用KSOAP2库访问webservice服务出现的服务端传入参数为null的问题解决

    ksoap2-android-3.0.0-jar 第三方库来调用.net 写的Web Service 如果没有参数,那么调用一切顺利,但是如果服务是带参数的,那么服务端接收的参数都是nul.      ...

  2. 在Android中调用KSOAP2库访问webservice服务出现的服务端返回AnyType{}

    最近在做毕业设计的时候,涉及到了安卓端访问web service服务端数据库,并返回一个值,当我把web service测试通过后,想写一个简单的安卓测试程序,来实现服务端数据库访问,通过web se ...

  3. 在Android中调用WebService

    某些情况下我们可能需要与Mysql或者Oracle数据库进行数据交互,有些朋友的第一反应就是直接在Android中加载驱动然后进行数据的增删改查.我个人不推荐这种做法,一是手机毕竟不是电脑,操作大量数 ...

  4. .NET调用Java写的WebService

    最近遇到一个用.net调用java写的webservice的应用,对方程序员提供了一个后缀为wsdl的文件,这个跟.Net里面生成的wsdl文件差不多,起初没什么概念就查了点资料,知道可以将这个wsd ...

  5. 【转】Android 学习笔记——利用JNI技术在Android中调用、调试C++代码

    原文网址:http://cherishlc.iteye.com/blog/1756762 在Android中调用C++其实就是在Java中调用C++代码,只是在windows下编译生成DLL,在And ...

  6. Android客户端调用Asp.net的WebService

    Android客户端调用Asp.net的WebService 我来说两句 |2011-11-23 13:39:15 在Android端为了与服务器端进行通信有几种方法:1.Socket通信2.WCF通 ...

  7. delphi7调用java写的webservice,在调用的时候弹出“wssecurityhandler:request does not contain required security header”

    delphi7调用java编写的webservice问题我用delphi7调用java写的webservice,在调用的时候弹出“wssecurityhandler:request does not ...

  8. [转][android][利用JNI技术在Android中调用、调试C++代码]

    在Android中调用C++其实就是在Java中调用C++代码,只是在windows下编译生成DLL,在Android中会生成Linux系统下的.so文件(好吧,其实我基本没用过Linux). 没写过 ...

  9. 如何在jmeter中调用自己写的java工具包

    本文介绍在jmeter中调用自己写java工具包,并非直接继承jmeter提供的java sample request接口. 工具/原料 jmeter eclipse 方法/步骤 通常用jmeter做 ...

随机推荐

  1. 编译caffe报错:_ZN5boost16exception_detail10bad_alloc_D2Ev

    具体报错信息很长的. text._ZN5boost16exception_detail10bad_alloc_D2Ev[_ZN5boost16exception_detail10bad_alloc_D ...

  2. iOS使用Safari调试UIWebView

    1.设置Safari "Safari"->"偏好设置"->"高级",勾选"在菜单栏中显示开发菜单" 2.设置 ...

  3. docker--wekan安装

    最近因为搭建开源看板网站的需要,玩了下docker 一开始在redhat上安装docker wget http://mirrors.163.com/.help/CentOS7-Base-163.rep ...

  4. [转][MSSQL]SQL Server 2008 记住密码功能

    本文转自:http://zhidao.baidu.com/link?url=V_laNOvutMin0kU3DUaMhLSFAYfgtz2IoEAjh8grNVPOZLpd8Pudb4iqZl88Tn ...

  5. node.js 基础学习 express安装使用

    安装好nodeJs,我们需要使用命令行中安装express. 我这里默认将Node.js安装在C:\Program Files\nodCejs\盘中. 在保持联网的状态下,依次输入如下命令. npm ...

  6. [Notes] Reading Notes on [Adaptive Robot Control – mxautomation J. Braumann 2015]

    Reading sources: 1.Johannes Braumann, Sigrid Brell-Cokcan, Adaptive Robot Control (ARC  ) Note: buil ...

  7. php基础-转义字符

    1.php是弱类型语言,定义变量时无需要定义 2.标量类型:整形.浮点型.字符串类型.布尔型 复合类型:数组.对象 其它类型:资源类型(resource如数据库连接,打开文件句柄,资源在不需要时都要释 ...

  8. 【转】 全世界最短的IE判定

    以前最短的IE判定借助于IE不支持垂直制表符的特性搞出来的. var ie = !+"\v1"; 仅仅需要7bytes!讲述外国人是如何把IE的判定从32 bytes一步步缩简成7 ...

  9. HTML之表单元素

    A.表单元素都是放在<form></form>标签内的.来看看表单的属性  属性 值 描述 accept MIME_type 规定通过文件上传来提交的文件的类型 accept- ...

  10. jquery checkbox选中、改变状态、change和click事件

    jquery判断checked的三种方法:.attr('checked); //看版本1.6+返回:”checked”或”undefined” ;1.5-返回:true或false.prop('che ...