Android开发之使用Web Service进行网络编程
使用Web Service进行网络编程
Android应用通常都是执行在手机平台上。手机系统的硬件资源是有限的,无论是存储能力还是计算能力都有限。在Android系统上开发、执行一些单用户、小型应用是可能的,
但对于须要进行大量的数据处理、复杂计算的应用。还是仅仅能部署在远程server上,Android应用将仅仅是充当这些应用的client。
为了让Android应用与远程server之间进行交互,能够借助子Java的RMI技术,但这要求远程server程序必须採用Java实现;也能够借助于CORBA技术。但这样的技术显得过于复杂,除此之外,Web
Service是一种不错的选择。
1.Web Service 平台概述
Web Service平台主要涉及的技术有SOAP(Simple Object Access Protocol,简单对象訪问协议),WSDL(
Web Service Description Language。Web Service描写叙述语言)。UDDI(UniversalDescription, Description and Integration,统一描写叙述、发现和整合协议)。
1.1. SOAP (简单对象訪问协议)
SOAP (SimpleObject Access Protocol,简单对象訪问协议)是一种具有扩展性的;XML消息协议。SOAP同意一个应用程序向还有一个应用程序发送XML消息,SOAP消息是从SOAP发送者传至SOAP接收者的单路消息,不论什么应用程序均可作为发送者或接收者。SOAP仅定义消息结构和消息处理的协议,与底层的传输协议独立。因此。SOAP协议能通过HTTP,
JMS 或SMTP协议传输。
SOAP依赖于XML文档来构建,一条SOAP消息就是一份特定的XML文档,SOAP消息包合例如以下三个主要元素:
Ø必需的<Envelope.../>根元素。SOAP消息相应的XML文档以该元素作为根元素。
Ø可选的<Header../>元素。包括SOAP消息的头信息。
Ø必需的<Body../>元素,包括全部的调用和响应信息。
就眼下的SOAP消息的结构来看。<Envelope.../>根元素的通常仅仅能包括两个子元素,第一个子元素是可选的<Header../>元素,第二个子元素是必需的<Body../>元素。
1.2. WSDL(WebService描写叙述语言)
WSDL (WebService Description Language, Web Service描写叙述语言)
使用 XML描写叙述Web Service。包含訪问和使用WebService所必需的信息,定义该Web
Service的位置、功能及怎样通信等描写叙述信息。
一般来说。仅仅要调用者可以获取WebService相应的WSDL,就行从中了解它所提供的服务及怎样调用Web
Service。由于一份WSDL文件淸晰地定义了三个方面的内容。
ØWHAT部分:用于定义Web
Service所提供的操作(或方法),也就是Web Service能做些什么。由WSDL中的<types. ../>、<message…/>、和<portTyp…/>元素定义。
ØHOW部分:用于定义怎样訪问Web
Service,包含数据格式详情和訪问Web Service操作的必要协议。
也就是定义了怎样訪问Web Service。
ØWHERE部分:用于定义Web
Service位于何处。怎样使用特定协议决定的网络地址(如URL)指定。该部分使用<service.../>元素定义。可在WSDL文件的最后部分看到<service.../>元素。
一份WSDL文档通常可分为两个部分:
Ø第一个部分定义了服务接口,它在WSDL中由<message.../>元素和<portType…/>两个元素组成,当中<message.../>元素定义了操作的交互方式。而<portType…/>元素里则可包括随意数量的<operation.../>元素。每一个<operation.../>元素代表一个同意远程调用的操作(即方法)。
ØWSDL的第二个部分定义了服务实现,它在WSDL中由<binding.../>元素和
<service.../>两个元素组成,当中<binding.../>定义使用特定的通信协议、数据编码模型和底层通信协议,将Web Service服务接口定义映射到详细实现。
而
<service.../>元素则包括一系列的<portType…/>子元素。< portType.../>子元素将会把绑定机制、服务訪问协议和端点地址结合在一起。
1.3. UDDI(统一描写叙述、发现和整合协议)
UDDI (UniversalDescription, Description and Integration,统一描写叙述、发现和整合协议)是一套信息注冊规范,它具有例如以下特点:
Ø基于Web。
Ø分布式。
UDDI包含一组同意企业向外注冊WebService、以使其它企业发现訪问的实现标准。
UDDI的核心组件是UDDI注冊中心,它使用XML文件来描写叙述企业及其提供的Web
Service, 通过使用UDDI, Web Service提供者能够对外注冊Web Service,从而同意其它企业来调用该企业注冊的Web
Service。Web Service提供者通过UDDI注冊中心的Web界面。将它所供的Web
Service的信息增加UDDI注冊中心,该Web Service就能够被发现和调用。
Web Service使用者也通过UDDI注冊中心査找、发现自己所需的服务。当Web
Service使用者找到自己所需的服务之后。能够将自己绑定到指定的Web Service提供者。再依据该 Web Service相应的WSDL文档来调用对方的服务。
2. 使用Android启用调用Web Service
Java本身提供了丰富的WebService支持,比方Sun公司制定的JAX-WS
2规范,还有 Apache开源组织所提供的Axis1、Axis2、CXF等,这些技术不仅能够用于很方便地对外提供Web
Service,也能够用于简化Web Service的client编程。
对于手机等小型设备而言,它们的计算资源、存储资源都十分有限。因此Android应用不大可能须要对外提供Web Service。Android应用通常仅仅是充当Web
Service的client,调用远程Web Serice。
Google为Android平台开发WebServiceclient提供了
ksoap2-android项目。但这个项目并未直接集成在Android平台中,还须要开发者自行下载。
2.1为Android应用添加ksoap2-android支持的下步骤。
1)登录http://code.google.eom/p/ksoap2-android/网站。该站网站有介绍下载ksoap2-androi项目的方法。
2)下载 ksoap2-android项目的
ksoap2-android-assembly-3.0.0-RC4.jar-with-dependencies. jar包。
3)将下载的jar包放到android项目的libs文件夹下就可以。
为Android项目加入了ksoap2-android包之后,接下来借助 ksoap2-android项目来调用WebService所暴露出来的操作。
2.2使用ksoap2-android调用Web Service操作的步驟例如以下:
1)创建HttpTransportSE对象,该对象用于调用WebService操作。
2)创建 SoapSerializationEnvelope对象。
提示:从名称来看SoapSerializationEnvelope代表一个SOAP消息封包;但ksoap2-android项目对
SoapSerializationEnvelope的处理比較特殊,它是HttpTransportSE调用WebService时信息的载体。client须要传入的參数,须要通过SoapSerializationEnvelope对象的bodyOut属性传给server;server响应生成的SOAP消息也通过该对象的body Out属性来获取。
3)创建SoapObject对象。创建该对象时须要传入所要调用WebService的命名空间、Web
Service方法名。
4)假设有參数须要传给Web Serviceserver端。调用SoapObject对象的addProperty(Stringname,Object
value)方法来设置參数,该方法的name參数指定參数名。value參数指定參数值。
5)调用SoapSerializationEnvelope的setOutputSoapObject()方法。或者直接对bodyOut属性赋值,将前两步创逆的SoapObject对象设为SoapSerializationEnvelope的传出SOAP消息体。
6)调用对象的call()方法,并以SoapSerializationEnvelope作为參数调用远程WebService。
7)调用完毕后,訪问SoapSerializationEnvelope对象的bodyln属性,该属性返回一个SoapObject对象。该对象就代表了Web
Service的返回消息。解析该SoapObject对象,就可以获取调用Web Service的返回值。
2.3实例:调用Web Service实现天气预报
在开发天气预报的Android应用之前,首先须要找到一个能够对外提供天气预报的Web Service,通过搜索,发现http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx网站
能够对外提供天气预报的WebService。因此程序将会调用该网站的Web Service来实现天气预报。
为了让应用界面更加美观,能够訪问http://www.webxml.com.cn/images/weather.zip下载各种天气图标,能够使用这些天气图标来美化应用。
本程序主要须要调用例如以下三个Web Seivice操作:
获取省份。
依据省份获取城市。
依据城市获取天气。
为了调用上面的三个WebService应用程序提供例如以下工具类。
publicclass { // staticfinal // staticfinal "http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx"; // publicstatic { // final // final ht.debug // final new // SoapObject soapObject = envelope.bodyOut // envelope.dotNet FutureTask<List<String>> task = new { @Override public throws { // ht.call(SERVICE_NS if { // SoapObject result = (SoapObject) envelope.bodyIn; SoapObject detail = (SoapObject) result.getProperty( methodName + // returnparseProvinceOrCity(detail); } returnnull; } }); new try { return } catch { e.printStackTrace(); } returnnull; } // publicstatic { // final // final ht.debug // SoapObject soapObject = // soapObject.addProperty("theRegionCode", // final new envelope.bodyOut // envelope.dotNet FutureTask<List<String>> task = new { @Override public throws { // ht.call(SERVICE_NS if { // SoapObject result = (SoapObject) envelope.bodyIn; SoapObject detail = (SoapObject) result.getProperty( methodName + // returnparseProvinceOrCity(detail); } returnnull; } }); new try { return } catch { e.printStackTrace(); } returnnull; } privatestatic { ArrayList<String> result = for { // result.add(detail.getProperty(i).toString().split(",")[0]); } return } publicstatic { final final ht.debug nbsp; final new SoapObject soapObject = soapObject.addProperty("theCityCode", envelope.bodyOut // envelope.dotNet FutureTask<SoapObject> task = new { @Override public throws { ht.call(SERVICE_NS SoapObject result = (SoapObject) envelope.bodyIn; SoapObject detail = (SoapObject) result.getProperty( methodName + return } }); new try { return } catch { e.printStackTrace(); } returnnull; } } |
上面的程序调用Web Service的方法还是没有改变,前面两个方法——获取系统支持的省份列表,依据省份获取城市列表——将远程Web
Service返回的数据解析成List<String>后返回。这样方便Android应用使用。因为第二个方法须要返回的数据量较多,所以程序直接返回了
SoapObject 对象。
上面的程序中调用WebService时将SoapSerializationEnvelope对象的dotNet属性设为
true——由于上面这个站点是通过.NET来对外提供WebService的,因此须要将 SoapSerializationEnvelope对象的
dotNet 属性设为 true。
有了上面的调用WebService的工具类之后,接下来能够在Activity中使用该工具类来获取天气服务信息。
该Activity使用了两个Spinner让用户选择省份、城市,当用户选择指定城市后,系统将会载入该程序的天气信息。
该程序的界面布局代码例如以下:
<? xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="@string/province"/> <!-- <Spinner android:id="@+id/province" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="@string/city"/> <!-- <Spinner android:id="@+id/city" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> <TextView android:id="@+id/weatherCurrent" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <!-- <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/todayWhIcon1" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <ImageView android:id="@+id/todayWhIcon2" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/weatherToday" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1"/> </LinearLayout> <!-- <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/tomorrowWhIcon1" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <ImageView android:id="@+id/tomorrowWhIcon2" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/weatherTomorrow" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1"/> </LinearLayout> <!-- <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/afterdayWhIcon1" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <ImageView android:id="@+id/afterdayWhIcon2" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/weatherAfterday" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1"/> </LinearLayout> </LinearLayout> |
当程序载入时,程序会调用WebServiceUtil的getProvinceList()方法来获取省份列表,并 使用第一个Spinner载入、显示全部省份:当用户改变选择了省份之后。程序会调用
WebServiceUtil的getCityListByProvince(Stringprovince)方法来获取该省份的所有城市:当用户改变选择城市之后,程序会调用WebServiceUtil的getWeatherByCity(StringcityName)方法 获取该城市的天气。
该Activity的代码例如以下:
publicclass { private private private private private private private private private private private private @Override publicvoid { super.onCreate(savedInstanceState); setContentView(R.layout.main); todayWhIcon1 todayWhIcon2 textWeatherToday tomorrowWhIcon1 tomorrowWhIcon2 textWeatherTomorrow afterdayWhIcon1 afterdayWhIcon2 textWeatherAfterday textWeatherCurrent // provinceSpinner citySpinner // List<String> provinces = WebServiceUtil.getProvinceList(); ListAdapter adapter = // provinceSpinner.setAdapter(adapter); // provinceSpinner.setOnItemSelectedListener(new { @Override publicvoid int { List<String> cities = WebServiceUtil .getCityListByProvince(provinceSpinner.getSelectedItem() .toString()); ListAdapter cityAdapter = cities); // citySpinner.setAdapter(cityAdapter); } @Override publicvoid { } }); // citySpinner.setOnItemSelectedListener(new { @Override publicvoid int { showWeather(citySpinner.getSelectedItem().toString()); } @Override publicvoid { } }); } privatevoid { String weatherToday = String weatherTomorrow = String weatherAfterday = String weatherCurrent = int int int // SoapObject detail = WebServiceUtil.getWeatherByCity(city); // weatherCurrent = detail.getProperty(4).toString(); // String date = detail.getProperty(7).toString(); weatherToday = weatherToday = weatherToday + weatherToday = weatherToday + + detail.getProperty(8).toString(); weatherToday = weatherToday + + detail.getProperty(9).toString() + iconToday[0] = parseIcon(detail.getProperty(10).toString()); iconToday[1] = parseIcon(detail.getProperty(11).toString()); // date = detail.getProperty(12).toString(); weatherTomorrow = weatherTomorrow = weatherTomorrow + weatherTomorrow = weatherTomorrow + + detail.getProperty(13).toString(); weatherTomorrow = weatherTomorrow + + detail.getProperty(14).toString() + iconTomorrow[0] = parseIcon(detail.getProperty(15).toString()); iconTomorrow[1] = parseIcon(detail.getProperty(16).toString()); // date = detail.getProperty(17).toString(); weatherAfterday = weatherAfterday = weatherAfterday + weatherAfterday = weatherAfterday + + detail.getProperty(18).toString(); weatherAfterday = weatherAfterday + + detail.getProperty(19).toString() + iconAfterday[0] = parseIcon(detail.getProperty(20).toString()); iconAfterday[1] = parseIcon(detail.getProperty(21).toString()); // textWeatherCurrent.setText(weatherCurrent); // textWeatherToday.setText(weatherToday); todayWhIcon1.setImageResource(iconToday[0]); todayWhIcon2.setImageResource(iconToday[1]); // textWeatherTomorrow.setText(weatherTomorrow); tomorrowWhIcon1.setImageResource(iconTomorrow[0]); tomorrowWhIcon2.setImageResource(iconTomorrow[1]); // textWeatherAfterday.setText(weatherAfterday); afterdayWhIcon1.setImageResource(iconAfterday[0]); afterdayWhIcon2.setImageResource(iconAfterday[1]); } // privateint { if return if return if return if return if return if return if return if return if return if return if return if return if return if return if return if return if return if return if return if return if return if return R.drawable.a_20; if return if return if return if return if return if return if return if return if return if return if return return } |
上面的Activity代码己经不再涉及调用WebService的代码了,仅仅是简单地调用Web
Service操作,解析Web Service返回的SOAP消息包。并把SOAP消息包中的数据显示出来。
未完待续..........
Android开发之使用Web Service进行网络编程的更多相关文章
- 使用Web Service进行网络编程-----Web Service简介
Android应用通常都是运行在手机平台上,手机系统的硬件资源是有限的,不管是存储能力还是计算能力都是有限的,在Android系统上开发.运行一些单用户.小型应用是可能的,但对于需要进行大量的数据处理 ...
- Android开发四大组件之Service(具体解释篇)
Android开发之四大组件--Service 一.Service 简单介绍 Service是android系统中的四大组件之中的一个(Activity.Service.BroadcastReceiv ...
- Android开发-基本概念(申明:来源于网络)
Android开发-基本概念(申明:来源于网络) 地址:http://blog.csdn.net/iwanghang/article/details/53505926
- Android开发之如何保证Service不被杀掉(broadcast+system/app
Android开发之如何保证Service不被杀掉(broadcast+system/app) 序言 最近项目要实现这样一个效果:运行后,要有一个service始终保持在后台运行,不管用户作出什么操作 ...
- 网络开发之使用Web Service和使用WCF服务
判断是否有可用网络连接可以通过NetworkInterface类中的GetIsNetworkAvailable来实现: bool networkIsAvailable = networkInterfa ...
- C#开发和调用Web Service
http://blog.csdn.net/h0322/article/details/4776819 1.1.Web Service基本概念 Web Service也叫XML Web Service ...
- Android调用Asp.net Web Service示例
WebService代码: using System; using System.Collections.Generic; using System.Linq; using System.Web; u ...
- [Teamcenter 2007 开发实战] 调用web service
前言 在TC的服务端开发中, 能够使用gsoap 来调用web service. 怎样使用 gsoap , 參考 gsoap 实现 C/C++ 调用web service 接下来介绍怎样在TC中进行 ...
- Android开发—— Native 与 Web 之架构抉择
前 言 移动App是对URL和搜索引擎的革命,当今移动App开发貌似出现两大阵营:Native 和 Web,各自都认为自己才是未来的趋势,Native操作流畅.迅速,Web开发周期相对较短,还能轻松跨 ...
随机推荐
- insmod: error inserting 'hello.ko': -1 Invalid module format
在学习编写linux驱动程序的时候,一般都是从写一个helloworld的模块開始. 可是在编译完毕后,进行模块载入的时候,有时会出现例如以下错误: insmod: error inserting ' ...
- 2015.04.28,外语,读书笔记-《Word Power Made Easy》 12 “如何奉承朋友” SESSION 36
1. the great and the small 拉丁词语animus(mind的意思),animus和另一个拉丁词根anima(life principle.soul.spirit),是许多单词 ...
- CodeForcess--609B--The Best Gift(模拟水题)
The Best Gift Time Limit: 2000MS Memory Limit: 262144KB 64bit IO Format: %I64d & %I64u Submi ...
- css元素垂直居中方法
1.Line-height 适用情景:单行文字垂直居中技巧 这个方式应该是最多人知道的了,常见于单行文字的应用,像是按钮这一类对象,或者是下拉框.导航此类元素最常见到的方式了.此方式的原理是在于将单行 ...
- jQuery应用实例3:鼠标经过显示离开隐藏
效果: 代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...
- 使用Latex写book类型文本的体会
晚上参考中科院上海交大清华北大等学校的模板,终于重新把博一时候没解决的问题解决了.中科院吴老师的CTeX论坛因为维护压力比较大不得不关了,查不到之前的Latex解决答案.经过一下午和一晚上的摸索,忽然 ...
- Android设计模式—— 观察者模式(以及EventBus的简单使用)
1.概述 观察者模式最常用的地方是GUI系统.订阅-发布系统.观察者模式的一个重要作用就是解耦,将观察者和被观察者解耦,使得他们之间的依赖性更小. 2.定义 定义对象间的一种一对多依赖关系,使得每当一 ...
- Android 蓝牙4.0的连接和通讯
1.加入权限 <uses-sdk android:minSdkVersion=" android:targetSdkVersion="/> <uses-featu ...
- JEE Spring-boot 简单的ioc写法。
什么是ioc,就是你可能会有一些生活必需品,这些东西你必须要用才能存活.但是你不是每天都回去买,去哪一家点去买.而这些用品会一直放在哪里,每一个商店就是一个容器,包裹着这些物品. 创建ioc项目,首先 ...
- 第四章 Python之文件处理
文件操作 文件操作一般分为三步:打开文件得到文件句柄并赋值给一个变量--->通过句柄对文件进行操作-->关闭文件 f=open(r'C:\Users\hesha\PycharmProjec ...