Android呼叫开发系列WebService
我在学习Android第一个问题是在发展进程中遇到Androidclient究竟是怎么用server与数据库交互它?问题是,我有初步接触Android这困扰了我一个非常大的问题。天直到几年前,我突然想到WebService能否够了吧?允许WebService充当server,完毕与server数据库操作相关的事情,而Androidclient仅仅要依照WebService方法參数的要求去调用即可了。在当时我对这个解决方式的实现还没模糊,我想这个问题也是初学Android的朋友肯定会想到的问题。那么如今就让我们动手去实现它吧。
这个程序我们演示怎样请求Web Service来获取服务端提供的数据。
因为我对C#比較熟悉。所以我优先使用自己熟悉的技术来搭建WebService的项目。非常easy我们就用VS工具创建一个Web服务应用程序(VS2008,而从VS2010開始优先使用WCF来创建服务应用程序了,只是用WCF框架创建WebService也是非常容易的)。
[WebMethod]public string DataTableTest(){DataTable dt = new DataTable("userTable");dt.Columns.Add("id",typeof(int));dt.Columns.Add("name", typeof(string));dt.Columns.Add("email", typeof(string));dt.Rows.Add(1, "gary.gu", "guwei4037@sina.com");dt.Rows.Add(2, "jinyingying", "345822155@qq.com");dt.Rows.Add(3, "jinyingying", "345822155@qq.com");dt.Rows.Add(4, "jinyingying", "345822155@qq.com");return Util.CreateJsonParameters(dt);}
这个WebService的方法非常easy,就是组建一个DataTable的数据类型,并通过CreateJsonParameters方法转化为JSON字符串。
这里面的DataTable能够改动成从数据库端读取数据到DataTable对象。
public static string CreateJsonParameters(DataTable dt){StringBuilder JsonString = new StringBuilder();if (dt != null && dt.Rows.Count > 0){JsonString.Append("{ ");JsonString.Append("\"Result_List\":[ ");for (int i = 0; i < dt.Rows.Count; i++){JsonString.Append("{ ");for (int j = 0; j < dt.Columns.Count; j++){if (j < dt.Columns.Count - 1){JsonString.Append("\"" + dt.Columns[j].ColumnName.ToString() + "\":" + "\"" + dt.Rows[i][j].ToString() + "\",");}else if (j == dt.Columns.Count - 1){JsonString.Append("\"" + dt.Columns[j].ColumnName.ToString() + "\":" + "\"" + dt.Rows[i][j].ToString() + "\"");}}if (i == dt.Rows.Count - 1){JsonString.Append("} ");}else{JsonString.Append("}, ");}}JsonString.Append("]}");return JsonString.ToString();}else{return null;}}
这种方法是我从网上随便找到的一个方法,比較土了,就是直接拼接JSON字符串(无所谓,这不是我们要关心的重点)。
WebService端准备好,就能够将其公布到IIS。公布方法跟站点一样,假设是本机的话。能够直接測试WebService方法返回得到的结果,比方调用后会得到例如以下结果:
这里肯定有人问,这外面是XML,里面又是JSON,这不是“四不像”吗?是的,我这样做是想说明一点,WebService是基于Soap的,传输数据的格式就是XML。所以这里得到XML文档是理所当然。假设你想得到纯净的JSON字符串,能够使用C#中的WCF框架(能够指定client返回JSON格式)或者Java中的Servlet(直接刷出JSON文本)。
好。接下来我们要做两件事:
1、请求这个WebService得到这个JSON字符串
2、格式化这个JSON字符串在Android中显示
我们先提供一个助手类,这是我自己动手封装了一下这两个操作所须要的方法。
/*** @author gary.gu 助手类*/
public final class Util {/*** @param nameSpace WS的命名空间* @param methodName WS的方法名* @param wsdl WS的wsdl的完整路径名* @param params WS的方法所须要的參数* @return SoapObject对象*/public static SoapObject callWS(String nameSpace, String methodName,String wsdl, Map<String, Object> params) {final String SOAP_ACTION = nameSpace + methodName;SoapObject soapObject = new SoapObject(nameSpace, methodName);if ((params != null) && (!params.isEmpty())) {Iterator<Entry<String, Object>> it = params.entrySet().iterator();while (it.hasNext()) {Map.Entry<String, Object> e = (Map.Entry<String, Object>) it.next();soapObject.addProperty(e.getKey(), e.getValue());}}SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);envelope.bodyOut = soapObject;// 兼容.NET开发的Web Serviceenvelope.dotNet = true;HttpTransportSE ht = new HttpTransportSE(wsdl);try {ht.call(SOAP_ACTION, envelope);if (envelope.getResponse() != null) {SoapObject result = (SoapObject) envelope.bodyIn;return result;} else {return null;}} catch (Exception e) {Log.e("error", e.getMessage());}return null;}/*** * @param result JSON字符串* @param name JSON数组名称* @param fields JSON字符串所包括的字段* @return 返回List<Map<String,Object>>类型的列表,Map<String,Object>相应于 "id":"1"的结构*/public static List<Map<String, Object>> convertJSON2List(String result,String name, String[] fields) {List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();try {JSONArray array = new JSONObject(result).getJSONArray(name);for (int i = 0; i < array.length(); i++) {JSONObject object = (JSONObject) array.opt(i);Map<String, Object> map = new HashMap<String, Object>();for (String str : fields) {map.put(str, object.get(str));}list.add(map);}} catch (JSONException e) {Log.e("error", e.getMessage());}return list;}
}
Tips:我们都知道C#中给方法加凝视,能够按3次“/”,借助于VS就能够自己主动生成。而在Eclipse其中,能够在方法上面输入“/**”然后按下回车就能够自己主动生成。
public class TestWS extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);RelativeLayout l = new RelativeLayout(this);Button button = new Button(l.getContext());button.setText("点击本机webservice");l.addView(button);setContentView(l);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {final String nameSpace = "http://tempuri.org/";final String methodName = "DataTableTest";final String wsdl = "http://10.77.137.119:8888/webserviceTest/Service1.asmx?WSDL";//调用WebService返回SoapObject对象SoapObject soapObject = Util.callWS(nameSpace, methodName,wsdl, null);if (soapObject != null) {//获得soapObject对象的DataTableTestResult属性的值String result = soapObject.getProperty("DataTableTestResult").toString();Toast.makeText(TestWS.this, result, Toast.LENGTH_SHORT).show();try {//将JSON字符串转换为List的结构List<Map<String, Object>> list = Util.convertJSON2List(result, "Result_List", new String[] { "id","name", "email" });//通过Intent将List传入到新的ActivityIntent newIntent = new Intent(TestWS.this,GridViewTest.class);Bundle bundle = new Bundle();//List一定是一个Serializable类型bundle.putSerializable("key", (Serializable) list);newIntent.putExtras(bundle);//启动新的ActivitystartActivity(newIntent);} catch (Exception e) {e.printStackTrace();}} else {System.out.println("This is null...");}}});}}
这里面有两点须要注意:
1、这个Activity并没有载入layout布局文件。而是通过代码创建了一个Button,这也是一种创建视图的方法。
2、通过Intent对象,我们将List<Map<String,Object>>传入到了新的Activity其中,这样的Intent之间的传值方式须要注意。
public class GridViewTest extends Activity {GridView grid;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_gridview);Intent intent = this.getIntent();Bundle bundle = intent.getExtras();//获得传进来的List<Map<String,Object>>对象@SuppressWarnings("unchecked")List<Map<String, Object>> list = (List<Map<String, Object>>) bundle.getSerializable("key");//通过findViewById方法找到GridView对象grid = (GridView) findViewById(R.id.grid01);//SimpleAdapter适配器填充//1.context 当前上下文,用this表示,或者GridViewTest.this//2.data A List of Maps.要求是List<Map<String,Object>>结构的列表。即数据源//3.resource 布局文件//4.from 从哪里来,即提取数据源List中的哪些key//5.to 到哪里去。即填充布局文件里的控件SimpleAdapter adapter = new SimpleAdapter(this, list,R.layout.list_item, new String[] { "id", "name", "email" },new int[] { R.id.id, R.id.name, R.id.email });//将GridView和适配器绑定grid.setAdapter(adapter);}}
先获得传过来的List对象,然后通过SimpleAdapter绑定到GridView。
activity_gridview.xml 布局文件:
<?
xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <GridView android:id="@+id/grid01" android:layout_width="fill_parent" android:layout_height="wrap_content" android:horizontalSpacing="1pt" android:verticalSpacing="1pt" android:numColumns="3" android:gravity="center"/> </LinearLayout>
list_item.xml 布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center_vertical"android:orientation="vertical" ><TextViewandroid:id="@+id/id"android:layout_width="wrap_content"android:layout_height="wrap_content" /><TextViewandroid:id="@+id/name"android:layout_width="wrap_content"android:layout_height="wrap_content" /><TextViewandroid:id="@+id/email"android:layout_width="wrap_content"android:layout_height="wrap_content" /></LinearLayout>
AndroidManifest.xml完整配置:
<?
xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.webservicedemo" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="14" /> <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".TestWS" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".GridViewTest" android:label="@string/app_name" > </activity> </application> </manifest>
终于在模拟器上面显示出了从数据库server获得的数据:
版权声明:本文博主原创文章,博客,未经同意不得转载。
Android呼叫开发系列WebService相关推荐
- Android蓝牙开发系列文章-蓝牙设备类型知多少?
在写<Android蓝牙开发系列文章-蓝牙音箱连接>时,计划细化出一篇讲解蓝牙设备类型的文章,现在它来了~ 阅读其他内容,可以点击<Android蓝牙开发系列文章-策划篇>,或 ...
- android 相机编程,Android相机开发系列
Android Camera Develop Series 简介 Android相机开发系列文章循序渐进,教你从一个没有任何功能的相机APP开始,逐步完善实现一般相机APP的各种功能,甚至还能拿来做图 ...
- Android蓝牙开发系列文章-蓝牙mesh(一)
在<Android蓝牙开发系列文章-策划篇>中我们对蓝牙专题的内容进行整体规划,现在让我们一点点揭开他的面纱~ 本文是关于蓝牙mesh的首篇文章,由好友CSDN博主yk150915提供,在 ...
- Android商城开发系列
Android商城开发系列(一)--开篇 Android商城开发系列(二)--App启动欢迎页面制作 Android商城开发系列(三)--使用Fragment+RadioButton实现商城底部导航栏 ...
- Android Camera开发系列(下)——自定义Camera实现拍照查看图片等功能
Android Camera开发系列(下)--自定义Camera实现拍照查看图片等功能 Android Camera开发系列(上)--Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片 上 ...
- Android蓝牙开发系列文章-蓝牙音箱连接
经过一段时间的折腾,我的Android Studio终于可以正常工作了,期间遇到的坑记录在了文章<创建Android Studio 3.5第一个工程遇到的坑>. 我们在<Androi ...
- Android自定义控件开发系列(零)——基础原理篇
在后边的文章中发现在说Android自定义时,有时候要重复解释很多东西,所以想想返回来增加一篇"基础原理篇",直接进入正题吧-- 首先的问题是:在Android项目开发中,什么时候 ...
- Android 快速开发系列 打造万能的ListView GridView 适配器
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38902805 ,本文出自[张鸿洋的博客] 1.概述 相信做Android开发的写 ...
- Android蓝牙开发系列文章-扫不到蓝牙设备,你的姿势对了吗?
在写<Android蓝牙开发系列文章-蓝牙音箱连接>时,计划细化出两篇文章,分别是: 关于蓝牙设备类型分类的,这个已经完成了,阅读请点击<Android蓝牙开发系列文章-蓝牙设备类型 ...
最新文章
- VS中C#读取app.config数据库配置字符串的三种方法(转)
- 【图论】图,实现图(三种方式),二分图 详解
- Linux安装jupyter debugger+Conda设置proxy代理
- (一)图像和图像工程
- GC算法以及垃圾回收器
- intel ssd toolbox 绿色单文件_你想要的大容量来了!影驰擎GA-E 16TB SSD上手:速度喜人-SSD,固态 ——快科技(驱动之家旗下媒体)-...
- Oracle MERGE用法
- java 泛型去重_泛型,list集合去重
- 今日分享:js制作一个简单的新年倒计时
- JAVA基于UDP的一个聊天程序
- PDF怎么转换成Word?这几个方法可以试试
- java 生成der_java – 我们如何将字符串从PEM转换为DER格式
- idea git操作
- POJ 2509 Peter's smokes
- mini2440 sd卡加载过程详解
- 【无标题】每个人女人,都需要一面黑色的镜子
- 常用网络工具使用说明(仅列出常用的功能,扩展功能可以单独查)
- C++字符串的压缩和解压(初学者的)
- 配置思科3550三层交换机用TELNET方式登录
- 怎么避开代还系统开发的套路?