我在学习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相关推荐

  1. Android蓝牙开发系列文章-蓝牙设备类型知多少?

    在写<Android蓝牙开发系列文章-蓝牙音箱连接>时,计划细化出一篇讲解蓝牙设备类型的文章,现在它来了~ 阅读其他内容,可以点击<Android蓝牙开发系列文章-策划篇>,或 ...

  2. android 相机编程,Android相机开发系列

    Android Camera Develop Series 简介 Android相机开发系列文章循序渐进,教你从一个没有任何功能的相机APP开始,逐步完善实现一般相机APP的各种功能,甚至还能拿来做图 ...

  3. Android蓝牙开发系列文章-蓝牙mesh(一)

    在<Android蓝牙开发系列文章-策划篇>中我们对蓝牙专题的内容进行整体规划,现在让我们一点点揭开他的面纱~ 本文是关于蓝牙mesh的首篇文章,由好友CSDN博主yk150915提供,在 ...

  4. Android商城开发系列

    Android商城开发系列(一)--开篇 Android商城开发系列(二)--App启动欢迎页面制作 Android商城开发系列(三)--使用Fragment+RadioButton实现商城底部导航栏 ...

  5. Android Camera开发系列(下)——自定义Camera实现拍照查看图片等功能

    Android Camera开发系列(下)--自定义Camera实现拍照查看图片等功能 Android Camera开发系列(上)--Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片 上 ...

  6. Android蓝牙开发系列文章-蓝牙音箱连接

    经过一段时间的折腾,我的Android Studio终于可以正常工作了,期间遇到的坑记录在了文章<创建Android Studio 3.5第一个工程遇到的坑>. 我们在<Androi ...

  7. Android自定义控件开发系列(零)——基础原理篇

    在后边的文章中发现在说Android自定义时,有时候要重复解释很多东西,所以想想返回来增加一篇"基础原理篇",直接进入正题吧-- 首先的问题是:在Android项目开发中,什么时候 ...

  8. Android 快速开发系列 打造万能的ListView GridView 适配器

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38902805 ,本文出自[张鸿洋的博客] 1.概述 相信做Android开发的写 ...

  9. Android蓝牙开发系列文章-扫不到蓝牙设备,你的姿势对了吗?

    在写<Android蓝牙开发系列文章-蓝牙音箱连接>时,计划细化出两篇文章,分别是: 关于蓝牙设备类型分类的,这个已经完成了,阅读请点击<Android蓝牙开发系列文章-蓝牙设备类型 ...

最新文章

  1. VS中C#读取app.config数据库配置字符串的三种方法(转)
  2. 【图论】图,实现图(三种方式),二分图 详解
  3. Linux安装jupyter debugger+Conda设置proxy代理
  4. (一)图像和图像工程
  5. GC算法以及垃圾回收器
  6. intel ssd toolbox 绿色单文件_你想要的大容量来了!影驰擎GA-E 16TB SSD上手:速度喜人-SSD,固态 ——快科技(驱动之家旗下媒体)-...
  7. Oracle MERGE用法
  8. java 泛型去重_泛型,list集合去重
  9. 今日分享:js制作一个简单的新年倒计时
  10. JAVA基于UDP的一个聊天程序
  11. PDF怎么转换成Word?这几个方法可以试试
  12. java 生成der_java – 我们如何将字符串从PEM转换为DER格式
  13. idea git操作
  14. POJ 2509 Peter's smokes
  15. mini2440 sd卡加载过程详解
  16. 【无标题】每个人女人,都需要一面黑色的镜子
  17. 常用网络工具使用说明(仅列出常用的功能,扩展功能可以单独查)
  18. C++字符串的压缩和解压(初学者的)
  19. 配置思科3550三层交换机用TELNET方式登录
  20. 怎么避开代还系统开发的套路?

热门文章

  1. SCCM部署操作系统失败:MP has rejected a request
  2. WCF访问iis元数据库失败--解决方法
  3. Android学习之JSON数据解析
  4. 十种工具审核网络安全
  5. 表间数据复制--SELECT表中的数据插入到新的表中(ORACLE,MSSQL)
  6. Linux教程 网络管理命令Netstat的使用
  7. Lync Server 2010迁移至Lync Server 2013部署系列 Part2:部署后端主服务器
  8. IntelliJ IDEA 环境常用设置整理
  9. WebRTC的拥塞控制技术转
  10. Coolblue的持续部署