Android 学习笔记之WebService实现远程调用+内部原理分析...
PS:终于可以抽出时间写写博客了,忙着学校的三周破实训外加替考...三周了,没怎么学习...哎...
学习内容:
1.WebService 实现远程方法的调用
什么是WebService...
WebService顾名思义,就是Web服务,WebService的数据传输格式是基于XML文档规范的,数据信息的传输就是以XML的形式来完成...由于XML不受平台和语言的限制,也正是由于这样的原因使得WebService可以实现远程调用,调用服务的语言可以是任意的.
什么是SOAP协议...
SOAP协议被称之为简单对象访问协议,它的作用是用来描述信息的传输格式...一条SOAP消息其实就是一个XML文档,SOAP可以规定一条消息是由谁进行发送的,并且由谁进行接收和处理,这就属于SOAP的封装,它基于XML的数据格式和Http的传输协议定义了一组标准的数据传输对象...说白了就是基于Http协议完成XML数据信息的传递...
什么是WSDL...
如果说SOAP用来完成数据信息的传递,那么WSDL就是规定数据信息以怎样的方式进行传递,WSDL是WebService的描述语言,目的是描述WebService上的每一个函数,我们知道函数调用的前提是:需要知道函数的功能,以及函数调用需要传递的相关参数,还有返回值,只有知道了这些点,我们才能够对一个函数进行调用,那么WSDL就是用来完成这个功能的,它基于XML文档,是一个机器可以解析的一个标准文档...其实就是一个描述应用函数的规范...
什么是uddi...
uddi是WebService的第三大要素,它的功能是完成WebService的注册和搜索,搜索其实就是在网络上的众多方法去查找我们需要的那个方法...注册则是生成一个新的函数...
以上就是WebService的三大要素,可能有点蒙,总结来说就是,uddi完成调用服务的查找,查找到了调用函数时,在获取WSDL之后,我们就可以对其进行调用,调用的过程中,传递的对象为SOAP封装好的对象...
如何调用WebService才是主要的....
WebService的调用过程其实非常的简单...我们只需要知道调用函数时需要传递的参数,以及函数对应的url就可以轻松完成远程方法的调用...
调用WebService需要使用到一个ksoap2-android-assembly-3.0.0-jar-with-dependencies.jar的包...这个包的下载地址,我会在最后进行给出...
先附上一段代码...这个用来调用某城市天气情况的查询的一个远程方法...
- package com.example.webservice_web;
- import java.io.IOException;
- import org.ksoap2.SoapEnvelope;
- import org.ksoap2.serialization.SoapObject;
- import org.ksoap2.serialization.SoapSerializationEnvelope;
- import org.ksoap2.transport.HttpTransportSE;
- import org.xmlpull.v1.XmlPullParserException;
- import android.os.Bundle;
- import android.app.Activity;
- import android.view.Menu;
- import android.view.View;
- import android.widget.EditText;
- import android.widget.TextView;
- import android.widget.Toast;
- public class MainActivity extends Activity implements View.OnClickListener {
- String NAMESPACE="http://WebXml.com.cn/"; //命名空间....
- String url="http://www.webxml.com.cn/webservices/weatherwebservice.asmx"; //方法的url..
- String METHOD_NAME="getWeatherbyCityName"; //需要调用的方法名...
- String SOAP_ACTION="http://WebXml.com.cn/getWeatherbyCityName"; //一般为命名空间+方法名称...
- /**
- * 上面这四种属性,我们可以通过方法的相关服务信息找到,相关信息其实就是WSDL文档..其中包含了上述信息的内容...
- * 通过WSDL明确了方法调用时需要传递的相关参数,我们就可以调用这个远程方法了...
- * */
- String weatherToday;
- SoapObject detail; //接收函数的返回值...
- String weatherNow;
- String weatherWillBe;
- private TextView tv;
- private EditText et;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- et=(EditText) findViewById(R.id.et);
- findViewById(R.id.bt).setOnClickListener(this);
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.main, menu);
- return true;
- }
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- switch(v.getId()){
- case R.id.bt:
- tv=(TextView) findViewById(R.id.tv);
- SoapObject rpc=new SoapObject(NAMESPACE, METHOD_NAME);
- String cityname=et.getText().toString();
- rpc.addProperty("theCityName", cityname);//添加参数..目的为了调用服务端提供的方法...
- /*
- * 实例化SoapSerializationEnvelope对象...
- * */
- SoapSerializationEnvelope envelope=new SoapSerializationEnvelope(SoapEnvelope.VER11);
- envelope.bodyOut=rpc;
- envelope.dotNet=true;
- envelope.setOutputSoapObject(rpc);//设置输出的参数为rpc
- HttpTransportSE ht=new HttpTransportSE(url);
- ht.debug=true;
- try {
- // Toast.makeText(getBaseContext(), "aa", Toast.LENGTH_LONG).show();
- ht.call(SOAP_ACTION, envelope);
- Toast.makeText(getBaseContext(), "bb", Toast.LENGTH_LONG).show();
- detail=(SoapObject) envelope.getResponse();
- String date=detail.getProperty(6).toString();
- weatherToday="\n天气:"+date.split(" ")[1];
- weatherToday=weatherToday+"\n气温:"+detail.getProperty(5).toString();
- weatherToday=weatherToday+"\n风力:"+detail.getProperty(7).toString();
- weatherNow=detail.getProperty(8).toString();
- weatherWillBe=detail.getProperty(9).toString();
- tv.setText(et.getText().toString()+weatherToday);
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (XmlPullParserException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
很简单的一段代码,但是有很多要说的地方...WebService的调用首先需要知道SOAP_ACTION,URL,Method,NAMESPACE...url我们可以直接获取的到...至于其他三个相关信息,我们可以通过查看WSDL文档直接就会获取到...那么知道了这些信息之后,我们才能够定义SOAP对象...SOAP把传递的参数,需要调用的方法,定义发送源和接收源...把这些信息封装在SOAP对象中,以数据流的形式发送到服务器,服务器在获取到这些数据之后,完成方法的调用,然后把返回的数据信息仍然以流的形式返回给客户端...这个客户端对返回的信息进行接收,那么整体就完成了远程方法的调用...下面说一下整体的实现过程...
首先我们需要实例化一个SoapObject...实例化SoapObject对象需要调用new函数生成...下面是调用的源码过程...通过传递命名空间和方法名来实例化一个SoapObject对象..
- /**
- * Creates a new <code>SoapObject</code> instance.
- *
- * @param namespace the namespace for the soap object
- * @param name the name of the soap object
- */
- public SoapObject(String namespace, String name) {
- this.namespace = namespace;
- this.name = name;
- }
那么实例化一个对象之后我们需要向这个对象中加入属性值,调用addProperty()方法...其实目的就是为了传递参数...下面是源码的调用过程...
- /**
- * Adds a property (parameter) to the object. This is essentially a sub element.
- *
- * @param name The name of the property
- * @param value the value of the property
- */
- //源码的意思就是为这个SoapObject对象配置两个属性,一个是名字属性,一个是值属性...
- public SoapObject addProperty(String name, Object value) {
- PropertyInfo propertyInfo = new PropertyInfo();
- propertyInfo.name = name;
- propertyInfo.type = value == null ? PropertyInfo.OBJECT_CLASS : value.getClass();
- propertyInfo.value = value;
- return addProperty(propertyInfo);
- }
上面的源码我们可以看到,这里的属性添加是通过实例化PropertyInfo对象,然后再次调用addProperty()函数..(注:两次调用的函数名字一样,但是方法却是不一样的...)这里解释一下PorpertyInfo对象的作用...PorpertyInfo是一个类,这个类的作用其实就是对所有属性信息的一个保存...(这里属性信息大家可能并不清楚...其实就是对Object,Integer,String)等基本类型进行保存,保存的方式通过getClass()...获取每一个类的相关信息,用于赋值...其实不难理解,我们在调用addProperty()传递参数时,需要有参数的名字和值,那么自然也要有参数的属性,否则在获取SoapObject对象中的参数时,就无法知道传递的参数到底是什么属性...这样PropertyInfo的name,value,type就被附上了初值...最后通过调用addProperty方法..这里的addProperty(propertyInfo)传递的已经转化成了PorpertyInfo对象了...
- /**
- * Adds a property (parameter) to the object. This is essentially a sub element.
- *
- * @param propertyInfo designated retainer of desired property
- */
- public SoapObject addProperty(PropertyInfo propertyInfo) {
- properties.addElement(propertyInfo);
- return this;
- }
这里调用properties.addElement()方法...addElement()方法...传递的参数是(E Object),这里的E,其实是Vector类型...Vector想必大家都清楚,是一个动态的对象数组,通过动态添加对象...这样Vector通过遍历的方式,将所有的属性对象都保存了起来...
- /**
- * Adds the specified object at the end of this vector.
- *
- * @param object
- * the object to add to the vector.
- */
- public synchronized void addElement(E object) {
- if (elementCount == elementData.length) {
- growByOne();
- }
- elementData[elementCount++] = object;
- modCount++;
- }
那么保存了封装所有参数的SoapObject对象..自然需要进行传递给远程方法...完成调用....这里远程方法的调用需要实例化SoapSerializationEnvelope对象...被称之为序列化后的对象...序列化的含义其实就是把一个类或者对象转化成流的形式,这样方便进行传输和存储,序列化后的类或对象无需人为进行处理,如果没有进行序列化,我们需要人为的定义存储,转发的格式,还有转化成流都需要我们人为去书写..这样会相当的复杂...并且在反序列化同时,一般的运行环境都会自动进行类和对象的还原..如果人为进行还原的话...仍然会非常的复杂...这样通过序列化上面的SoapObject对象...就可以指定SoapObject对象传输的方式是以流的方式进行传输了...这里调用下面方法...
SoapSerializationEnvelope envelope=new SoapSerializationEnvelope(SoapEnvelope.VER11);下面是源码过程....这里实例化对象需要指定WebService的版本信息...
- public SoapSerializationEnvelope(int version)
- {
- super(version);
- addMapping(enc, ARRAY_MAPPING_NAME, PropertyInfo.VECTOR_CLASS);
- DEFAULT_MARSHAL.register(this);
- }
这里调用了addMapping方法将保存了PropertyInfo的对象数组以键值对的形式保存在HashTable中...最后通过register方法将保存好的对象完成序列化封装的注册...完成了封装注册之后...还需要设置相关的属性...这里完成相关属性的设置...表示封装的对象为我们先前定义的SoapObject对象...设置访问的服务器为.Net服务器...设置最后输出的对象仍然为SoapObject对象...
- envelope.bodyOut=object;
- envelope.dotNet=true;
- envelope.setOutputSoapObject(object);
封装好了所有的对象之后,就需要使用Http进行Url的连接了...通过HttptransportSE完成WSDL地址的连接...最后使用call方法完成该方法的调用...这样就完成了远程方法的调用,如果函数没有返回数据,那么我们就不需要进行获取了...只需要完成数据信息的上传就可以了..如果有返回数据,我们还需要定义一个SoapObject来完成返回数据的接收...通过返回的数据信息获取我们需要的相关信息并显示在自己的应用程序中,这样就完成了远程方法的调用...
- HttpTransportSE ht=new HttpTransportSE(url);
- ht.debug=true;
- try {
- ht.call(SOAP_ACTION, envelope);
detail=(SoapObject) envelope.getResponse();- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (XmlPullParserException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
就如同刚开始的代码,最后返回的是一个SoapObject对象,我们接收到这个对象之后就可以获取一些我们想要的数据信息了...
(注:使用网络服务需要设置权限... <uses-permission android:name="android.permission.INTERNET"/>)....
这样就完成了远程方法的调用,实现了不同平台的应用程序之间完成通信...实现了Web服务的无缝连接...
Android 学习笔记之WebService实现远程调用+内部原理分析...的更多相关文章
- 【转】Pro Android学习笔记(五三):调试和分析(1):Debug视图和DDMS视图
目录(?)[-] Debug视图 DDMS视图 查看应用运行状态 进入debug状态 HPROF Thread信息 Method信息 Stop 截图 UI层次架构信息 其它的 Tab中提供的功能 我们 ...
- 【转】 Pro Android学习笔记(七八):服务(3):远程服务:AIDL文件
目录(?)[-] 在AIDL中定义服务接口 根据AIDL文件自动生成接口代码 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.n ...
- Android学习笔记(一)
目录 Android学习笔记(一) 一.JDK.Android SDK 二.部分项目结构 三.字符串引用 四.外层build.gradle详解 五.app->build.gradle详解 六.日 ...
- Android 学习笔记之Volley(七)实现Json数据加载和解析...
学习内容: 1.使用Volley实现异步加载Json数据... Volley的第二大请求就是通过发送请求异步实现Json数据信息的加载,加载Json数据有两种方式,一种是通过获取Json对象,然后 ...
- Android学习笔记之JSON数据解析
转载:Android学习笔记44:JSON数据解析 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,为Web应用开发提供了一种 ...
- udacity android 学习笔记: lesson 4 part b
udacity android 学习笔记: lesson 4 part b 作者:干货店打杂的 /titer1 /Archimedes 出处:https://code.csdn.net/titer1 ...
- Android学习笔记36:使用SQLite方式存储数据
在Android中一共提供了5种数据存储方式,分别为: (1)Files:通过FileInputStream和FileOutputStream对文件进行操作.具体使用方法可以参阅博文<Andro ...
- Android学习笔记之Activity详解
1 理解Activity Activity就是一个包含应用程序界面的窗口,是Android四大组件之一.一个应用程序可以包含零个或多个Activity.一个Activity的生命周期是指从屏幕上显示那 ...
- 【转】 Pro Android学习笔记(八八):了解Handler(2):什么是Handler
文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ 之前我们有一篇很好的博文<Andro ...
随机推荐
- WIFI WPA1/2 Crack for Windows
0x00 前言 目前WIFI WPA破解主要 以“aircrack-ng”为代表,运行于Linux系统( 如Kali Linux ),Windows系统比较少见,主要是Windows系统下WIFI网卡 ...
- Linux 中的grep命令单引号,不加任何参数以及双引号的作用
单引号: 可以说是所见即所得:即将单引号内的内容原样输出,或者描述为单引号里面看到的是什么就会输出什么.单引号''是全引用,被单引号括起的内容不管是常量还是变量者不会发生替换. 双引号: 把双引号内的 ...
- C#中的Linq to Xml详解
这篇文章主要介绍了C#中的Linq to Xml详解,本文给出转换步骤以及大量实例,讲解了生成xml.查询并修改xml.监听xml事件.处理xml流等内容,需要的朋友可以参考下 一.生成Xml 为了能 ...
- 用Pomelo 搭建一个简易的推送平台
前言 实际上,个人感觉,pomelo 目前提供的两个默认sioconnector和hybridconnector 使用的协议并不适合用于做手机推送平台,在pomelo的一份公开ppt里面,有提到过, ...
- python 相关安装和配置
永久链接: http://michaelzqm.iteye.com/blog/1841966 预览文章: python环境搭建 2013-04-04 博客分类: 综合 一. window环境安 ...
- javascript 中的getter,setter
1.什么是getter,什么是setter? getter 是一种获得属性值的方法,setter是一种设置属性值的方法. 2.怎么定义? 有2种办法: 在对象初始化的时候定义 在对象定义后的时候定义 ...
- Android ImageView src与backgroud
在XML中添加ImageView时,有两个可以设置图片的地方,一个是android:src,一个是android:background,这两个的区别: src是图片内容,显示在前面的,backgrou ...
- GameOver
GameOver. 正了八经的觉得GameOver了.该开始新的了.
- kwm备忘
brew install homebrew/binary/kwm ==> Tapping homebrew/binary Cloning into '/usr/local/Library/Tap ...
- 通过PowerShell发送TCP请求
很多时候我们需要通过Socket发送特定的TCP请求给服务器的特定端口来实现探测服务器的指定端口所开启的服务.很多语言都有相应的方法实现上述需求,当然,PowerShell也不例外,比如我们要发送一个 ...