• Android使用ksoap2-android调用WebService学习


    转自 Android使用ksoap2-android调用WebService学习

     之前主要做客户端UI交互,很少处理数据和接触服务端,但现在的移动设备根本不可能离得开网络连接,数据的交换。最近学习的是在android端如何去调用远程WebService,都说WebService是一种基于SOAP协议的远程调用标准,对于这个协议理解不深,知道webservice可以将不同操作系统平台、不同语言、不同技术整合到一块,android SDK没有直接调用webservice的库,最常用的是借助ksoap2-android这个第三方SDK,点击打开链接,然后和其他第三方jar包一样导入android项目中即可。

            对于WebService服务器具体的编写,现阶段自己不了解,暂且使用网络免费的WebService进行学习http://www.webxml.com.cn/zh_cn/index.aspx,利用这个来写一个简单的国内天气预报的查询,代码编写参照《疯狂Android讲义》相关部分,自己做部分修改。

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

           以下是几个主要的方法:

    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;

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

    7.获取服务器响应返回的SOAP消息:

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

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

    在这个天气预报的demo中需要多次调用webservice,将方法写在一个工具类中,代码如下:

    [java] view plaincopy
     
    1. <span style="font-family:Comic Sans MS;font-size:18px;">package com.example.webservicedemo;  
    2.   
    3. import java.io.IOException;  
    4. import java.util.ArrayList;  
    5. import java.util.List;  
    6. import org.ksoap2.SoapEnvelope;  
    7. import org.ksoap2.SoapFault;  
    8. import org.ksoap2.serialization.SoapObject;  
    9. import org.ksoap2.serialization.SoapSerializationEnvelope;  
    10. import org.ksoap2.transport.HttpTransportSE;  
    11. import org.xmlpull.v1.XmlPullParserException;  
    12.   
    13. public class WebServiceUtil {  
    14.     // 定义webservice的命名空间  
    15.     public static final String SERVICE_NAMESPACE = "http://WebXml.com.cn/";  
    16.     // 定义webservice提供服务的url  
    17.     public static final String SERVICE_URL = "http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx";  
    18.   
    19.     // 调用远程webservice获取省份列表  
    20.     public static List<String> getProvinceList() {  
    21.         // 调用 的方法  
    22.         String methodName = "getRegionProvince";  
    23.         // 创建HttpTransportSE传输对象  
    24.         HttpTransportSE ht = new HttpTransportSE(SERVICE_URL);  
    25.         try {  
    26.             ht.debug = true;  
    27.             // 使用SOAP1.1协议创建Envelop对象  
    28.             SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(  
    29.                     SoapEnvelope.VER11);  
    30.             // 实例化SoapObject对象  
    31.             SoapObject soapObject = new SoapObject(SERVICE_NAMESPACE,  
    32.                     methodName);  
    33.             envelope.bodyOut = soapObject;  
    34.             // 设置与.NET提供的webservice保持较好的兼容性  
    35.             envelope.dotNet = true;  
    36.   
    37.             // 调用webservice  
    38.             ht.call(SERVICE_NAMESPACE + methodName, envelope);  
    39.             if (envelope.getResponse() != null) {  
    40.                 // 获取服务器响应返回的SOAP消息  
    41.                 SoapObject result = (SoapObject) envelope.bodyIn;  
    42.                 SoapObject detail = (SoapObject) result.getProperty(methodName  
    43.                         + "Result");  
    44.                 // 解析服务器响应的SOAP消息  
    45.                 return parseProvinceOrCity(detail);  
    46.             }  
    47.         } catch (SoapFault e) {  
    48.             // TODO Auto-generated catch block  
    49.             e.printStackTrace();  
    50.         } catch (IOException e) {  
    51.             // TODO Auto-generated catch block  
    52.             e.printStackTrace();  
    53.         } catch (XmlPullParserException e) {  
    54.             // TODO Auto-generated catch block  
    55.             e.printStackTrace();  
    56.         }  
    57.         return null;  
    58.     }  
    59.   
    60.     // 根据省份获取城市列表  
    61.     public static List<String> getCityListsByProvince(String province) {  
    62.         // 调用的方法  
    63.         String methodName = "getSupportCityString";  
    64.         // 创建httptransportSE传输对象  
    65.         HttpTransportSE ht = new HttpTransportSE(SERVICE_URL);  
    66.         ht.debug = true;  
    67.         // 实例化SoapObject对象  
    68.         SoapObject soapObject = new SoapObject(SERVICE_NAMESPACE, methodName);  
    69.         // 添加一个请求参数  
    70.         soapObject.addProperty("theRegionCode", province);  
    71.         // 使用soap1.1协议创建envelop对象  
    72.         SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(  
    73.                 SoapEnvelope.VER11);  
    74.         envelope.bodyOut = soapObject;  
    75.         // 设置与.NET提供的webservice保持较好的兼容性  
    76.         envelope.dotNet = true;  
    77.   
    78.         // 调用webservice  
    79.         try {  
    80.             ht.call(SERVICE_NAMESPACE + methodName, envelope);  
    81.             if (envelope.getResponse() != null) {  
    82.                 // 获取服务器响应返回的SOAP消息  
    83.                 SoapObject result = (SoapObject) envelope.bodyIn;  
    84.                 SoapObject detail = (SoapObject) result.getProperty(methodName  
    85.                         + "Result");  
    86.                 // 解析服务器响应的SOAP消息  
    87.                 return parseProvinceOrCity(detail);  
    88.             }  
    89.         } catch (SoapFault e) {  
    90.             // TODO Auto-generated catch block  
    91.             e.printStackTrace();  
    92.         } catch (IOException e) {  
    93.             // TODO Auto-generated catch block  
    94.             e.printStackTrace();  
    95.         } catch (XmlPullParserException e) {  
    96.             // TODO Auto-generated catch block  
    97.             e.printStackTrace();  
    98.         }  
    99.         return null;  
    100.     }  
    101.   
    102.     // 解析省份或城市  
    103.     public static List<String> parseProvinceOrCity(SoapObject detail) {  
    104.         ArrayList<String> result = new ArrayList<String>();  
    105.         for (int i = 0; i < detail.getPropertyCount(); i++) {  
    106.             // 解析出每个省份  
    107.             result.add(detail.getProperty(i).toString().split(",")[0]);  
    108.         }  
    109.         return result;  
    110.     }  
    111.   
    112.     // 根据城市字符串获取相应天气情况  
    113.     public static SoapObject getWeatherByCity(String cityName) {  
    114.         String methodName = "getWeather";  
    115.         HttpTransportSE ht = new HttpTransportSE(SERVICE_URL);  
    116.         ht.debug = true;  
    117.         SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(  
    118.                 SoapEnvelope.VER11);  
    119.         SoapObject soapObject = new SoapObject(SERVICE_NAMESPACE, methodName);  
    120.         soapObject.addProperty("theCityCode", cityName);  
    121.         envelope.bodyOut = soapObject;  
    122.         envelope.dotNet = true;  
    123.   
    124.         try {  
    125.             ht.call(SERVICE_NAMESPACE + methodName, envelope);  
    126.             SoapObject result = (SoapObject) envelope.bodyIn;  
    127.             SoapObject detail = (SoapObject) result.getProperty(methodName  
    128.                     + "Result");  
    129.             return detail;  
    130.         } catch (IOException e) {  
    131.             // TODO Auto-generated catch block  
    132.             e.printStackTrace();  
    133.         } catch (XmlPullParserException e) {  
    134.             // TODO Auto-generated catch block  
    135.             e.printStackTrace();  
    136.         }  
    137.         return null;  
    138.     }  
    139.   
    140. }  
    141.   
    142.   
    143. </span>  


     

    上面这个便是主要实现远程调用webservice的代码,其他实现在activity中完成即可,但是这里也会涉及到一个问题,就是Android多线程问题,在调用webservice时,为了防止ANR的出现,不能在主线程中进行,需要另开子线程执行,,因为子线程涉及到UI更新,Android主线程是线程不安全的,也就是说,更新UI只能在主线程中更新,子线程中操作是危险的.便要涉及Handler的使用了,实在是不才,自己更多时候习惯使用AsyncTask来代替Handler(还是要重新琢磨下Handler的使用方法),因为操作起来比较简单方便,下面是项目中异步操作类中的一个:

    [java] view plaincopy
     
    1. <span style="font-family:Comic Sans MS;font-size:18px;">package com.example.webservicedemo;  
    2.   
    3. import java.util.List;  
    4. import android.os.AsyncTask;  
    5. import android.widget.Spinner;  
    6.   
    7. public class ProvinceAsyncTask extends AsyncTask<String, String, List<String>> {  
    8.     private MainActivity activity;  
    9.     private List<String> provinces;  
    10.     private Spinner sp_province;  
    11.       
    12.     public ProvinceAsyncTask (MainActivity activity,Spinner sp_province){  
    13.         this.activity = activity;  
    14.         this.sp_province = sp_province;  
    15.     }  
    16.   
    17.     @Override  
    18.     protected List<String> doInBackground(String... params) {   
    19.         // TODO Auto-generated method stub  
    20.         provinces = WebServiceUtil.getProvinceList();  
    21.         return null;  
    22.     }  
    23.   
    24.     @Override  
    25.     protected void onPostExecute(List<String> result) {  
    26.         // TODO Auto-generated method stub  
    27.         ListAdapter adapter = new ListAdapter(activity, provinces);  
    28.         sp_province.setAdapter(adapter);  
    29.           
    30.     }  
    31. }  
    32.   
    33.   
    34. </span>  


    可以看出来比较简单,在doInBackground中执行调用webservice,在onPostExecute中执行列表刷新展示

    最后附上该demo的代码,希望可以对初涉及android调用webservice的朋友有帮助

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

  • 相关阅读:
    函数指针的调用方式
    C++构造函数和析构函数顺序
    往android主项目中添加辅助项目
    Qt每次运行都是重新编译问题
    函数参数检验的研究
    动态链接库和静态链接库的区别(未完待续)
    MySQL 查看最大连接数, 当期连接数.
    Linux 命令
    Ext treelist 动态切换TreeStore
    Java 日期加减计算.
  • 原文地址:https://www.cnblogs.com/sunseine/p/4082774.html
Copyright © 2020-2023  润新知