zoukankan      html  css  js  c++  java
  • 在Android中调用C#写的WebService(附源代码)

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

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

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

    复制代码
    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的类库

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

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

    image

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

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

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

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

    image

    复制代码
    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);
        }
    复制代码

    3、分析Android调用WebService的代码

    我们的重点将放在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”)
    image

    (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) {
            // 1、指定webservice的命名空间和调用的方法名
            
            SoapObject request = new SoapObject(Namespace, MethodName);
            // 2、设置调用方法的参数值,如果没有参数,可以省略,
            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());
                }
            }
            // 3、生成调用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;
        }
    复制代码

    4、运行代码

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

    示例代码

    Android端源代码

    WebService源代码

  • 相关阅读:
    jquery加入购物车飞入的效果
    jQuery点击div其他地方隐藏div
    移动对meta的定义
    ZOJ
    博弈dp入门 POJ
    ZOJ 2967计算几何+单调栈
    牛客训练41D最小相似度bfs
    球的体积并
    二进制上的数位dpPOJ 3252
    数位dp入门 HDU 2089 HDU 3555
  • 原文地址:https://www.cnblogs.com/ywsoftware/p/3752560.html
Copyright © 2011-2022 走看看