基于 Android 和 WCF 技术的软件开发

宁可枝头抱香死,何曾吹落北风中。这篇文章主要讲述基于 Android 和 WCF 技术的软件开发相关的知识,希望能为你提供帮助。
最近,同学的同学找我做了一款简单的安卓手机软件,第一次,一个人,做一个完整的项目。所以,在这里总结一下完整的开发流程和步骤,方便后来人入门学习。


其实,我是一个新手,没有系统的学过android也没有系统的学过WCF,这些都是自己一点一点尝试出来的。


先说一下我的基础:

  • 安卓在三年前接触过,当时乱看一气。主要看的网站就是这个(http://www.fenby.com);
  • 今年三月份,深入学习了数据库相关知识,对于数据的增删改查,三范式,E-R有了深刻了解;
  • 今天五月份,负责一个软件开发的服务器端的接口编写,也就是用WCF技术实现接口。

如今,自己做了一个项目。下面开始正式的项目介绍。
本系统设计三部分内容:
  • 数据库的设计;
  • 服务器端接口开发;
  • Android客户端功能实现和接口调用。

数据库的结构设计
说实话,数据库的设计完全就是另外一门技术,能够“设计表的结构,灵活使用增删改查等语句”,就够了。
设计的时候,要符合三范式,注意表和属性的命名规范即可。
在这里推荐大家使用一个PowerDesigner软件,这个软件上手快,可视化的方式设计E-R图,自动生成各种数据库系统sql脚本,还能快速生成用户字典等文本文件。在这里就不多说了,读者可以自己了解。这个软件只是提高效率仅此而已。

值 得强调一下

前期使用阿里“云服务器ECS”,这一个服务器就够了,这个服务器及可以配置IIS发布站点也可以安装数据库,用这一个就够了。
基于 Android 和 WCF 技术的软件开发

文章图片



后期,数据明显数据量剧增,就需要使用“阿里云数据库RDS”,使用mysql数据库会比SQL Server 每个月的使用费用便宜一点,毕竟MySQL开源嘛,所以,推荐使用MySQL数据库。所以,最开始做项目的时候,就推荐使用MySQL数据库。
基于 Android 和 WCF 技术的软件开发

文章图片




关于云服务器ECS 我还想说点:(反正我是第一次用的时候,好多迷惑)
  1. 上面说了,一开始部署的时候不用租用“阿里云数据库RDS”;
  2. 购买完以后,会给你服务器IP,自己设置账号密码以后,就可以在自己电脑上进行远程操作啦;
  3. 在服务器中发布站点和在自己电脑发布站点的步骤一样,没有什么特殊的。
远程操作:
  1. 开始菜单那输入 mstsc;
  2. 输入账号密码即可。
基于 Android 和 WCF 技术的软件开发

文章图片



服务器端
服务器概述这一部分主要由两部分组成:
  • 接口的编写(VS 2013 的.NET平台WCF技术)
  • 接口的部署(IIS)


接口的编写本人第一次接触WCF技术的时候,是由一位在职场工作多年的技术经理告诉我的,也就是他带领我完成了今年五月份的项目。


要做好WCF部分工作,要注意一下几个方面:

  • 什么是WCF技术?
  • 怎么创建一个WCF工程?
  • 怎么调试和运行一个WCF工程?
  • WCF怎么和数据库建立链接?
  • 怎么配置数据库服务器的连接地址(也就是IP)?
  • 返回值 用什么样的规范?如何编写返回值 ?


什么是WCF技术
这个大家自己百度就好了,我就不抄袭别人的东西了。(   传送门:WCF技术 - 百度百科    )。其实,我没管那么多,能用就行。




怎么创建一个WCF工程
这个,也来一个传送门吧!(   传送门:新建WCF项目    )



如何调试和运行一个WCF工程
在上面的博客连接中已经有说明,这里在强调一下。F5快速调试。(就是这么厉害)




  WCF怎么和数据库建立连接
其实,WCF和SQL Server 还是很好连接的,毕竟都是微软自家东西(   传送门:WCF的数据库连接和访问    )


配置数据库服务器的连接地址(也就是IP)
不过,按照上面的方式,就把数据库的连接字符串写在程序内部了,如果服务器IP地址改变,或者更换服务器的时候,就需要重新打开原项目工程进行IP地址的修改(最终的编译结果会生成一个dll文件),这是一件我们不愿意做而且很麻烦的事情,所以,要注意,把连接字符串写在web.config文件中。这样就可以灵活的修改IP地址。(传送门:连接字符串的修改操作)




返回值 用什么样的规范?如何编写返回值 ?
对于WCF而言,返回值 都是用JSON串的形式返回的,所以,对于一般的查询结果我们可以自己拼接出来返回一个状态值 。


例如:如果验证这个用户是否合法,就可以返回

  • {" State" :1}表示合法;
  • {“State” :0}表示不合法;
  • {“State” :2}表示服务器异常。



当然,你还可以选择自己增加更多的内容。例如:

  • {“UserID” :10001 , " Token" : " 8fc043eb-0722-4c11-a0f4-8b9194066a35" }   //返回用户ID和令牌(GUID)。



只要把你想要返回的东西以JSON格 式返回就可以了,剩下的就是Android客户端的调用。如何调用,我们会后续讲解。


对于WCF返回JSON格 式,有一个现成的dll文件,直接引用即可。(   传送门:用NuGet安装NewtonSoft.json    )


IIS环境配置和接口发布其实,对于这样的项目工程而言,接口的发布之前还需要Android端和接口在线调试。也就是说,一个人开打VS2013,另一个人打开ADT,面对面直接调试,这样VS端的可以打断点,当Android端的调用接口的时候,VS会自动停在断点处,这样调试和查看参数更加方便。(这个没有找到对应的传送门,后面讲解)


本节三部分组成:

  • IIS环境配置
  • 在线调试
  • 接口发布



IIS环境的配置
在调试和接口发布之前,一定要配置好IIS环境。


关于IIS环境的配置,推荐两个博客结合安装(   传送门:IIS部署和WCF发布    IIS部署    )


这两个博客把WCF发布的内容也讲述了,其实,现在还没有到发布的时候,此时需要的是IIS配置好以后,进行在线调试,等一切都调试通过以后,就可以发布了。




在线调试
这个没有找到合适博客,在这里,本人说明一下。


打开IIS配置文件
基于 Android 和 WCF 技术的软件开发

文章图片


按照上面的步骤,打开IIS配置文件。


找到对应的绑定在VS调试的时候,你就可以知道自己的调试端口号是什么,然后就“ctrl + F”找到对应的端口即可,赋值 当前行,把localhost改为本机IP地址,保存,关闭。
基于 Android 和 WCF 技术的软件开发

文章图片




打开防火墙如图,按照序号操作,为了简化文章长度,我把最后的显示结果截成此图,实际上,三个窗体的显示顺序整好与现在的层级显示关系相反。
基于 Android 和 WCF 技术的软件开发

文章图片


剩下的就不说了,百度上有打开防火墙端口的教程。(   传送门:打开防火墙端口    )


添加服务
基于 Android 和 WCF 技术的软件开发

文章图片


基于 Android 和 WCF 技术的软件开发

文章图片


只需要把localhost修改为本机IP即可。


通过以上步骤,Android客户端就可以访问这个连接了。也就是,同一个局域网的用户,都可以访问这个网站了。


剩下的工作就是在线调试。


接口发布
这个接口发布和上面的调试有什么区别呢?


这个问题问的好。

  • 上面的调试是在VS打开的情况下才可以访问,而且端口号是VS自己确定的;
  • 此时的发布完全由自己控制,就是自己发布一个网站的过程,端口号(如果和上面的端口号不一样,要打开防火墙端口号)可以任意设置,而且不打开VS也可以访问网站。



在上文中已经发过博客链接,在这里,再发一次(传送门:WCF发布    重点看第三部分)


还有一点值 得说明,在自己发布接口的根目录下,新建一个文件夹,用于存放签名且加固好的APK,以此来提供用户下载。


但是,在网页中,下载APK需要一些站点的设置,请看传送门(   如何配置IIS使其支持APK文件的下载    )


Android客户端的开发



此部分分为两部分设计:

  • 基本的界面设计和控件使用触发事件的响应;
  • 服务器接口调用。



界面的设计不同软件类型的开发,使用的界面控件和布局效果肯定大不一样,所以,在这里,只说明本人在制作软件过程中使用到的相关技术和知识。




数据的存储问题
例如,当用户登陆过apk以后,肯定不希望下一次登录的时候还输入账号密码等信息,所以,此时需要把用户输入的数据进行本地存储,安卓平台有五种数据存储方式,我使用的是“用SharedPreferences存储数据”。这个相对简单,而且只是三两个数据,这个足够了。(   传送门:Android平台进行数据存储的五大方式    )



// 保存登录数据:账号,密码,ID,令牌 到 data 文件中 SharedPreferences sp2 = (LoginActivity.this).getSharedPreferences(" data" ,MODE_PRIVATE); SharedPreferences.Editor editor = sp2.edit(); // 获取编辑对象//editor.clear(); editor.putString(" USERID" , uid); editor.putString(" PASSWORD" , psw_md5.getMD5(psw)); editor.putInt(" ID" , id); editor.putString(" TOKEN" , token); editor.commit(); // 提交保存修改


// 用户退出,清空data中的数据 SharedPreferences sp = ExitActivity().getSharedPreferences(" data" , MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); // 获取编辑对象 editor.clear(); editor.commit(); // 提交保存修改





自定义ListView控件
这个技术在安卓开发中利用的最多了,纵观网上各种做法,推荐这篇博客(   传送门:Android 自定义ListView)




ListView的滚动事件
如何监听ListView的滚动事件?如果内容滑动到最底部,如何加载新数据?


在网上发现了这篇文章,感觉不错,大家可以看看。(   传送门:ListView加载数据    )


其实,ListView加载数据的事件就是这个,在loadData()的地方写好自己的数据加载代码即可。

listview.setOnScrollListener(new OnScrollListener() { //AbsListView view 这个view对象就是listview @Override       public void onScrollStateChanged(AbsListView view, int scrollState) {         if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {           if (view.getLastVisiblePosition() == view.getCount() - 1) {             loadData();           }         }       }       @Override       public void onScroll(AbsListView view, int firstVisibleItem,           int visibleItemCount, int totalItemCount) {             lastItem = firstVisibleItem + visibleItemCount - 1 ;       } });


就简单的列举几个吧!做项目的时候,每个人都会遇到各种不一样的问题,自己百度解决就好了。


接口调用这才是,重点!!!




调用接口,编写客户端函数
对于WCF这样的服务器接口,一般来说,推荐使用KSOP。这个还是跟简单的,在服务器中,包含很多接口,那么在自己的客户端上,你就对应设计每个接口即可。


为了有所了解,请先看文章(传送门:Android平台调用WebService详解    Android调用WCF    Android调用C#的WebService),这三篇文章写的很好,很详细。


不过,我还是贴一段代码,来显示一下我认为的规范开发。

package com.DLMU.freeride.WCFService; 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.util.Log; public class Services { private static String NameSpace = " http://tempuri.org/" ; private static String URL = " http://你的IP:端口号/Service1.svc" ; private static String MethodName_login = " login" ; public String Login(String phonenum, String password) {String methodName = MethodName_login; // 指定WebService的命名空间和调用的方法名 SoapObject soapObject = new SoapObject(NameSpace, methodName); // 设置需调用WebService接口需要传入的参数token soapObject.addProperty(" phonenum" , phonenum); soapObject.addProperty(" password" , password); // 生成调用WebService方法的SOAP请求信息,并指定SOAP的版本 SoapSerializationEnvelope envelope = new SoapSerializationEnvelope( SoapEnvelope.VER11); envelope.bodyOut = soapObject; // 设置是否调用的是dotNet开发的WebService envelope.dotNet = true; // 等价于envelope.bodyOut = rpc; envelope.setOutputSoapObject(soapObject); HttpTransportSE trans = new HttpTransportSE(URL); trans.debug = true; // 使用调试功能try { // 调用WebService String SOAP_ACTION = " http://tempuri.org/IService1/" + methodName; Log.d(" WCF" , SOAP_ACTION); trans.call(SOAP_ACTION, envelope); } catch (IOException e) { System.out.println(" IOException" ); e.printStackTrace(); } catch (XmlPullParserException e) { System.out.println(" XmlPullParserException" ); e.printStackTrace(); }// 获取返回的数据 SoapObject result = (SoapObject) envelope.bodyIn; // 获取返回的结果 String json = null; if (result == null) { json = " 接口调用失败" ; } else { json = result.getProperty(0).toString(); } Log.d(" WCF" , json); return json; }}


注意这里,一个参数的大小写要和服务器接口的大小写保持一致,而且先后顺序也不能改变。

// 设置需调用WebService接口需要传入的参数token soapObject.addProperty(" phonenum" , phonenum); soapObject.addProperty(" password" , password);





3.2.2   接口的实际调用
如果你认为,编写完对象中的方法就能直接调用,那你就错了。使用接口函数的时候还要注意一点。见代码

try { Thread thread = new Thread(new Runnable() {@Override public void run() { Services s = new Services(); String result = s.Login(uid, psw); if (result.length() > = 12) { //在我的接口中,定义{" State" :0},表示账号密码错误,长度为11 //合法用户应该返回:{“UserID” :10001 , " Token" : " 8fc043eb-0722-4c11-a0f4-8b9194066a35" },长度大于11 //所以用12来做比较// 身份合理,正确跳转 Intent intent = new Intent( LoginActivity.this, MainActivity.class); startActivity(intent); finish(); } else {Looper.prepare(); Toast.makeText(LoginActivity.this, " 账号或密码错误" , Toast.LENGTH_SHORT) .show(); Looper.loop(); } } }); thread.start(); } catch (Exception e) { e.printStackTrace(); }


注意,接口调用要写在线程中,而且要try{}catch{}。


到此,接口的工作就完成了,因为接口返回的数据格 式是JSON串,所以,需要在客户端进行JSON串解析。

//{ // [{" ID" :1," TEL" :" 123456" }], // [{" ID" :2," TEL" :" 123457" }], // [{" ID" :3," TEL" :" 123458" }], // [{" ID" :4," TEL" :" 123454" }] //}JSONTokener jsonTokener = new JSONTokener(data); JSONArray array = (JSONArray) jsonTokener.nextValue(); for (int i = 0; i < array.length(); i++) { // 提取数据 JSONObject item = array.getJSONObject(i); int id = item.getInt(" ID" ); String tel = item.getString(" TEL" ); }


根据上面的例子,我对于一个JSON串,如果遇到{[],[],[]},我们需要先使用JSONArray;如果遇到{},我们使用JSONObject来获取数据。


至此,教程结束。




一个上午的时间,都在编写这教程。
其实,做一个安卓手机联网软件不是很难。大家都可以试试。
其实就由两部分组成:客户端 + 服务器。
搞好客户端,写好服务器,做好客户端的接口调用,部署好服务器的站点,足矣。
【基于 Android 和 WCF 技术的软件开发】
































































































    推荐阅读